From bdca79e5ac19143b5766dc4a74d1e0d370841727 Mon Sep 17 00:00:00 2001 From: Petru Lingurar Date: Wed, 1 Aug 2018 09:09:11 +0300 Subject: [PATCH 01/52] Bug 1478970 - Can't update Nightly from about:firefox or notification bar - Android O+; r=jchen As per https://android-developers.googleblog.com/2017/08/making-it-safer-to-get-apps-on-android-o.html and https://developer.android.com/reference/android/Manifest.permission.html#REQUEST_INSTALL_PACKAGES after targeting API 26 we need a new permission to be able to install Apks. MozReview-Commit-ID: BF28HTkwYTN --HG-- extra : rebase_source : cbbbbfb8578d1430810c773d2da99ecd99e69615 --- mobile/android/base/FennecManifest_permissions.xml.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mobile/android/base/FennecManifest_permissions.xml.in b/mobile/android/base/FennecManifest_permissions.xml.in index 70e5cac67602..0739abbbd3b3 100644 --- a/mobile/android/base/FennecManifest_permissions.xml.in +++ b/mobile/android/base/FennecManifest_permissions.xml.in @@ -36,6 +36,11 @@ +#ifdef MOZ_UPDATER + + +#endif + #ifdef MOZ_ANDROID_BEAM From 2b958d46dec47eba0eaf66aca908df77f4364171 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 1 Aug 2018 07:52:13 +0000 Subject: [PATCH 02/52] Bug 1478668 - windows key store adapter, r=keeler OS key-store adapter for Windows Credential Manager. It looks like Windows doesn't allow locking the credential manager without locking the desktop. So `lock` and `unlock` are no-ops here. Depends on D2487. Differential Revision: https://phabricator.services.mozilla.com/D2550 --HG-- extra : moz-landing-system : lando --- .../manager/ssl/CredentialManagerSecret.cpp | 127 ++++++++++++++++++ .../manager/ssl/CredentialManagerSecret.h | 29 ++++ security/manager/ssl/OSKeyStore.cpp | 4 + security/manager/ssl/moz.build | 5 + .../manager/ssl/tests/unit/test_oskeystore.js | 7 +- 5 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 security/manager/ssl/CredentialManagerSecret.cpp create mode 100644 security/manager/ssl/CredentialManagerSecret.h diff --git a/security/manager/ssl/CredentialManagerSecret.cpp b/security/manager/ssl/CredentialManagerSecret.cpp new file mode 100644 index 000000000000..eadb96086989 --- /dev/null +++ b/security/manager/ssl/CredentialManagerSecret.cpp @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CredentialManagerSecret.h" + +#include +#include + +#include "mozilla/Logging.h" +#include "mozilla/SyncRunnable.h" + +// This is the implementation of CredentialManagerSecretSecret, an instantiation +// of OSKeyStore for Windows. It uses the system credential manager, hence the +// name. + +using namespace mozilla; + +LazyLogModule gCredentialManagerSecretLog("credentialmanagersecret"); +struct ScopedDelete +{ + void operator()(CREDENTIALA* cred) { CredFree(cred); } +}; + +template +struct ScopedMaybeDelete +{ + void operator()(T* ptr) + { + if (ptr) { + ScopedDelete del; + del(ptr); + } + } +}; +typedef std::unique_ptr> ScopedCREDENTIALA; + +CredentialManagerSecret::CredentialManagerSecret() {} + +CredentialManagerSecret::~CredentialManagerSecret() {} + +nsresult +CredentialManagerSecret::Lock() +{ + // The Windows credential manager can't be locked. + return NS_OK; +} + +nsresult +CredentialManagerSecret::Unlock() +{ + // The Windows credential manager is always unlocked when the user is logged + // in. + return NS_OK; +} + +nsresult +CredentialManagerSecret::StoreSecret(const nsACString& aSecret, + const nsACString& aLabel) +{ + if (aSecret.Length() > CRED_MAX_CREDENTIAL_BLOB_SIZE) { + // Windows doesn't allow blobs larger than CRED_MAX_CREDENTIAL_BLOB_SIZE + // bytes. + MOZ_LOG(gCredentialManagerSecretLog, + LogLevel::Debug, + ("StoreSecret secret must not be larger than 512 bytes (got %d)", + aSecret.Length())); + return NS_ERROR_FAILURE; + } + CREDENTIALA cred = { 0 }; + cred.Type = CRED_TYPE_GENERIC; + const nsCString& label = PromiseFlatCString(aLabel); + cred.TargetName = const_cast(label.get()); + cred.CredentialBlobSize = aSecret.Length(); + cred.CredentialBlob = (LPBYTE)PromiseFlatCString(aSecret).get(); + cred.Persist = CRED_PERSIST_LOCAL_MACHINE; + cred.UserName = ""; + + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credwritea + BOOL ok = CredWriteA(&cred, 0); + if (!ok) { + MOZ_LOG(gCredentialManagerSecretLog, + LogLevel::Debug, + ("CredWriteW failed %d", GetLastError())); + NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult +CredentialManagerSecret::DeleteSecret(const nsACString& aLabel) +{ + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creddeletea + BOOL ok = CredDeleteA(PromiseFlatCString(aLabel).get(), CRED_TYPE_GENERIC, 0); + int error = GetLastError(); + if (!ok && error != ERROR_NOT_FOUND) { + MOZ_LOG(gCredentialManagerSecretLog, + LogLevel::Debug, + ("CredDeleteA failed %d", error)); + NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult +CredentialManagerSecret::RetrieveSecret(const nsACString& aLabel, + /* out */ nsACString& aSecret) +{ + aSecret.Truncate(); + PCREDENTIALA pcred_raw = nullptr; + const nsCString& label = PromiseFlatCString(aLabel); + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credreada + BOOL ok = CredReadA(label.get(), CRED_TYPE_GENERIC, 0, &pcred_raw); + ScopedCREDENTIALA pcred(pcred_raw); + if (!ok) { + MOZ_LOG(gCredentialManagerSecretLog, + LogLevel::Debug, + ("CredReadA failed %d", GetLastError())); + return NS_ERROR_FAILURE; + } + MOZ_ASSERT(pcred); + aSecret.Assign(reinterpret_cast(pcred->CredentialBlob), + pcred->CredentialBlobSize); + return NS_OK; +} diff --git a/security/manager/ssl/CredentialManagerSecret.h b/security/manager/ssl/CredentialManagerSecret.h new file mode 100644 index 000000000000..b31aeac45bee --- /dev/null +++ b/security/manager/ssl/CredentialManagerSecret.h @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CredentialManagerSecret_h +#define CredentialManagerSecret_h + +#include "OSKeyStore.h" +#include "nsString.h" + +class CredentialManagerSecret final : public AbstractOSKeyStore +{ +public: + CredentialManagerSecret(); + + virtual nsresult RetrieveSecret(const nsACString& label, + /* out */ nsACString& secret) override; + virtual nsresult StoreSecret(const nsACString& secret, + const nsACString& label) override; + virtual nsresult DeleteSecret(const nsACString& label) override; + virtual nsresult Lock() override; + virtual nsresult Unlock() override; + + virtual ~CredentialManagerSecret(); +}; + +#endif // CredentialManagerSecret_h diff --git a/security/manager/ssl/OSKeyStore.cpp b/security/manager/ssl/OSKeyStore.cpp index fc2eb4fb2c75..350454a81479 100644 --- a/security/manager/ssl/OSKeyStore.cpp +++ b/security/manager/ssl/OSKeyStore.cpp @@ -15,6 +15,8 @@ #include "LibSecret.h" #elif defined(XP_MACOSX) #include "KeychainSecret.h" +#elif defined(XP_WIN) +#include "CredentialManagerSecret.h" #else #include "NSSKeyStore.h" #endif @@ -33,6 +35,8 @@ OSKeyStore::OSKeyStore() mKs.reset(new LibSecret()); #elif defined(XP_MACOSX) mKs.reset(new KeychainSecret()); +#elif defined(XP_WIN) + mKs.reset(new CredentialManagerSecret()); #else mKs.reset(new NSSKeyStore()); #endif diff --git a/security/manager/ssl/moz.build b/security/manager/ssl/moz.build index 2fdea5b11caf..3eb9ae6a469a 100644 --- a/security/manager/ssl/moz.build +++ b/security/manager/ssl/moz.build @@ -155,6 +155,11 @@ if CONFIG['OS_ARCH'] == 'Darwin': '-framework Security' ] +if CONFIG['OS_ARCH'] == 'WINNT': + UNIFIED_SOURCES += [ + 'CredentialManagerSecret.cpp', + ] + IPDL_SOURCES += [ 'PPSMContentDownloader.ipdl', ] diff --git a/security/manager/ssl/tests/unit/test_oskeystore.js b/security/manager/ssl/tests/unit/test_oskeystore.js index 3ebec65810b4..1df729a317d9 100644 --- a/security/manager/ssl/tests/unit/test_oskeystore.js +++ b/security/manager/ssl/tests/unit/test_oskeystore.js @@ -15,8 +15,7 @@ const LABELS = ["mylabel1", async function delete_all_secrets() { let keystore = Cc["@mozilla.org/security/oskeystore;1"] .getService(Ci.nsIOSKeyStore); - for (let i in LABELS) { - let label = LABELS[i]; + for (let label of LABELS) { if (await keystore.asyncSecretAvailable(label)) { await keystore.asyncDeleteSecret(label); ok(!await keystore.asyncSecretAvailable(label), label + " should be deleted now."); @@ -114,8 +113,8 @@ add_task(async function() { await encrypt_decrypt_test(); await delete_all_secrets(); - if (AppConstants.platform == "macosx") { - ok(!keystore.isNSSKeyStore, "OS X should use the non-NSS implementation"); + if (AppConstants.platform == "macosx" || AppConstants.platform == "win") { + ok(!keystore.isNSSKeyStore, "OS X and Windows should use the non-NSS implementation"); } if (keystore.isNSSKeyStore) { From 5341019c70731f722f816b9c6e5c4dcce89edb9e Mon Sep 17 00:00:00 2001 From: Petru Gurita Date: Wed, 25 Jul 2018 09:00:42 +0300 Subject: [PATCH 03/52] Bug 1319793 - [marionette harness tests] Default to not swallow stdout from pytest. r=whimboo Added the flag 'capture --no' to the harness_unit tests. Stdout is now displayed by default. MozReview-Commit-ID: HZj3vntLcKI --HG-- extra : rebase_source : 4de9697cf8cae7ed1707049609812de6f6e22387 --- .../harness/marionette_harness/tests/harness_unit/test_httpd.py | 2 +- .../tests/harness_unit/test_marionette_arguments.py | 2 +- .../tests/harness_unit/test_marionette_harness.py | 2 +- .../tests/harness_unit/test_marionette_runner.py | 2 +- .../tests/harness_unit/test_marionette_test_result.py | 2 +- .../harness/marionette_harness/tests/harness_unit/test_serve.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_httpd.py b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_httpd.py index 653023ec6102..2105170bd70d 100644 --- a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_httpd.py +++ b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_httpd.py @@ -89,4 +89,4 @@ def test_handler(server): if __name__ == "__main__": - mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-') + mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-', '--capture', 'no') diff --git a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_arguments.py b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_arguments.py index 4b0a7574590f..bb888275e21f 100644 --- a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_arguments.py +++ b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_arguments.py @@ -66,4 +66,4 @@ def test_parse_opt_args_emulator(mach_parsed_kwargs, arg_name, arg_dest, arg_val if __name__ == '__main__': - mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-') + mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-', '--capture', 'no') diff --git a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_harness.py b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_harness.py index a49ce94e3a46..7d438a6dde51 100644 --- a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_harness.py +++ b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_harness.py @@ -107,4 +107,4 @@ def test_harness_sets_up_default_test_handlers(mach_parsed_kwargs): if __name__ == '__main__': - mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-') + mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-', '--capture', 'no') diff --git a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_runner.py b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_runner.py index d1b67d2fa6d7..55ed5416f28d 100644 --- a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_runner.py +++ b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_runner.py @@ -507,4 +507,4 @@ def test_option_run_until_failure(mach_parsed_kwargs, repeat, run_until_failure) if __name__ == '__main__': - mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-') + mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-', '--capture', 'no') diff --git a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_test_result.py b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_test_result.py index 645124453df1..b4c1f2e8b7b1 100644 --- a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_test_result.py +++ b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_test_result.py @@ -53,4 +53,4 @@ def test_crash_is_recorded_as_error(empty_marionette_test, if __name__ == '__main__': - mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-') + mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-', '--capture', 'no') diff --git a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_serve.py b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_serve.py index 87948204621f..6e0363fcad1f 100644 --- a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_serve.py +++ b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_serve.py @@ -66,4 +66,4 @@ def test_where_is(): if __name__ == "__main__": - mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-') + mozunit.main('-p', 'no:terminalreporter', '--log-tbpl=-', '--capture', 'no') From 3536af633eea0579cde61754dc9a867da5c50490 Mon Sep 17 00:00:00 2001 From: Panos Astithas Date: Thu, 26 Jul 2018 12:47:30 +0300 Subject: [PATCH 04/52] Bug 1472921 - Fix sampling interval persistence for values <1ms. r=julienw MozReview-Commit-ID: TxKzT8MCZY --HG-- extra : rebase_source : 534e6a93928428cd24c306a0f78737d7d6a1d36f --- browser/components/nsBrowserGlue.js | 8 +++++++- devtools/client/performance-new/browser.js | 7 +++++-- devtools/client/performance-new/store/reducers.js | 4 ++-- .../test/chrome/test_perf-settings-interval.html | 4 ++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index a29b22ff06c2..a3db91ef2401 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -1811,7 +1811,7 @@ BrowserGlue.prototype = { _migrateUI: function BG__migrateUI() { // Use an increasing number to keep track of the current migration state. // Completely unrelated to the current Firefox release number. - const UI_VERSION = 71; + const UI_VERSION = 72; const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL; let currentUIVersion; @@ -2142,6 +2142,12 @@ BrowserGlue.prototype = { } } + if (currentUIVersion < 72) { + // Migrate performance tool's recording interval value from msec to usec. + let pref = "devtools.performance.recording.interval"; + Services.prefs.setIntPref(pref, Services.prefs.getIntPref(pref, 1) * 1000); + } + // Update the migration version. Services.prefs.setIntPref("browser.migration.version", UI_VERSION); }, diff --git a/devtools/client/performance-new/browser.js b/devtools/client/performance-new/browser.js index 8a8f4dae9788..fd61dbcb23cf 100644 --- a/devtools/client/performance-new/browser.js +++ b/devtools/client/performance-new/browser.js @@ -111,7 +111,9 @@ async function getRecordingPreferences(preferenceFront, defaultSettings = {}) { ), ]); - return { entries, interval, features, threads }; + // The pref stores the value in usec. + const newInterval = interval / 1000; + return { entries, interval: newInterval, features, threads }; } /** @@ -130,7 +132,8 @@ async function setRecordingPreferences(preferenceFront, settings) { ), preferenceFront.setIntPref( `devtools.performance.recording.interval`, - settings.interval + // The pref stores the value in usec. + settings.interval * 1000 ), preferenceFront.setCharPref( `devtools.performance.recording.features`, diff --git a/devtools/client/performance-new/store/reducers.js b/devtools/client/performance-new/store/reducers.js index 5d6ef030c680..626c66d9301c 100644 --- a/devtools/client/performance-new/store/reducers.js +++ b/devtools/client/performance-new/store/reducers.js @@ -55,10 +55,10 @@ function isSupportedPlatform(state = null, action) { // is opened. These should be persisted between sessions. See Bug 1453014. /** - * The setting for the recording interval. + * The setting for the recording interval. Defaults to 1ms. * @param {number} state */ -function interval(state = 1, action) { +function interval(state = 1000, action) { switch (action.type) { case "CHANGE_INTERVAL": return action.interval; diff --git a/devtools/client/performance-new/test/chrome/test_perf-settings-interval.html b/devtools/client/performance-new/test/chrome/test_perf-settings-interval.html index 05d9abff201b..581d7c510f71 100644 --- a/devtools/client/performance-new/test/chrome/test_perf-settings-interval.html +++ b/devtools/client/performance-new/test/chrome/test_perf-settings-interval.html @@ -31,8 +31,8 @@ await mountAndInitializeComponent(); - is(selectors.getInterval(getState()), 1, - "The interval starts out as 1"); + is(selectors.getInterval(getState()), 1000, + "The interval starts out as 1000"); is(recordingPreferencesCalls.length, 0, "No calls have been made"); From 26aea6f1ff3ddddcd1b942ad48bca87b7d496f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Tue, 31 Jul 2018 21:20:07 +0200 Subject: [PATCH 05/52] Bug 1479874 - On Windows 10, let active menu bar items inherit their color from the title bar. r=Felipe MozReview-Commit-ID: 1FxqSz2U6Lo --HG-- extra : rebase_source : 287de9e88d4240f5088d9b239a1d1ef220d738c8 --- browser/themes/windows/browser-aero.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/themes/windows/browser-aero.css b/browser/themes/windows/browser-aero.css index 0c67e5a9e161..37e6e3a499c6 100644 --- a/browser/themes/windows/browser-aero.css +++ b/browser/themes/windows/browser-aero.css @@ -173,7 +173,7 @@ } @media (-moz-windows-default-theme) { - #main-menubar > menu { + #main-menubar > menu[_moz-menuactive="true"] { color: inherit; } From fa7b36bf434c5306c191dd498f55b966040e9aea Mon Sep 17 00:00:00 2001 From: Dorel Luca Date: Wed, 1 Aug 2018 12:26:14 +0300 Subject: [PATCH 06/52] Backed out changeset e80000bf992c (bug 1478668) for build bustage --- .../manager/ssl/CredentialManagerSecret.cpp | 127 ------------------ .../manager/ssl/CredentialManagerSecret.h | 29 ---- security/manager/ssl/OSKeyStore.cpp | 4 - security/manager/ssl/moz.build | 5 - .../manager/ssl/tests/unit/test_oskeystore.js | 7 +- 5 files changed, 4 insertions(+), 168 deletions(-) delete mode 100644 security/manager/ssl/CredentialManagerSecret.cpp delete mode 100644 security/manager/ssl/CredentialManagerSecret.h diff --git a/security/manager/ssl/CredentialManagerSecret.cpp b/security/manager/ssl/CredentialManagerSecret.cpp deleted file mode 100644 index eadb96086989..000000000000 --- a/security/manager/ssl/CredentialManagerSecret.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "CredentialManagerSecret.h" - -#include -#include - -#include "mozilla/Logging.h" -#include "mozilla/SyncRunnable.h" - -// This is the implementation of CredentialManagerSecretSecret, an instantiation -// of OSKeyStore for Windows. It uses the system credential manager, hence the -// name. - -using namespace mozilla; - -LazyLogModule gCredentialManagerSecretLog("credentialmanagersecret"); -struct ScopedDelete -{ - void operator()(CREDENTIALA* cred) { CredFree(cred); } -}; - -template -struct ScopedMaybeDelete -{ - void operator()(T* ptr) - { - if (ptr) { - ScopedDelete del; - del(ptr); - } - } -}; -typedef std::unique_ptr> ScopedCREDENTIALA; - -CredentialManagerSecret::CredentialManagerSecret() {} - -CredentialManagerSecret::~CredentialManagerSecret() {} - -nsresult -CredentialManagerSecret::Lock() -{ - // The Windows credential manager can't be locked. - return NS_OK; -} - -nsresult -CredentialManagerSecret::Unlock() -{ - // The Windows credential manager is always unlocked when the user is logged - // in. - return NS_OK; -} - -nsresult -CredentialManagerSecret::StoreSecret(const nsACString& aSecret, - const nsACString& aLabel) -{ - if (aSecret.Length() > CRED_MAX_CREDENTIAL_BLOB_SIZE) { - // Windows doesn't allow blobs larger than CRED_MAX_CREDENTIAL_BLOB_SIZE - // bytes. - MOZ_LOG(gCredentialManagerSecretLog, - LogLevel::Debug, - ("StoreSecret secret must not be larger than 512 bytes (got %d)", - aSecret.Length())); - return NS_ERROR_FAILURE; - } - CREDENTIALA cred = { 0 }; - cred.Type = CRED_TYPE_GENERIC; - const nsCString& label = PromiseFlatCString(aLabel); - cred.TargetName = const_cast(label.get()); - cred.CredentialBlobSize = aSecret.Length(); - cred.CredentialBlob = (LPBYTE)PromiseFlatCString(aSecret).get(); - cred.Persist = CRED_PERSIST_LOCAL_MACHINE; - cred.UserName = ""; - - // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credwritea - BOOL ok = CredWriteA(&cred, 0); - if (!ok) { - MOZ_LOG(gCredentialManagerSecretLog, - LogLevel::Debug, - ("CredWriteW failed %d", GetLastError())); - NS_ERROR_FAILURE; - } - return NS_OK; -} - -nsresult -CredentialManagerSecret::DeleteSecret(const nsACString& aLabel) -{ - // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creddeletea - BOOL ok = CredDeleteA(PromiseFlatCString(aLabel).get(), CRED_TYPE_GENERIC, 0); - int error = GetLastError(); - if (!ok && error != ERROR_NOT_FOUND) { - MOZ_LOG(gCredentialManagerSecretLog, - LogLevel::Debug, - ("CredDeleteA failed %d", error)); - NS_ERROR_FAILURE; - } - return NS_OK; -} - -nsresult -CredentialManagerSecret::RetrieveSecret(const nsACString& aLabel, - /* out */ nsACString& aSecret) -{ - aSecret.Truncate(); - PCREDENTIALA pcred_raw = nullptr; - const nsCString& label = PromiseFlatCString(aLabel); - // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credreada - BOOL ok = CredReadA(label.get(), CRED_TYPE_GENERIC, 0, &pcred_raw); - ScopedCREDENTIALA pcred(pcred_raw); - if (!ok) { - MOZ_LOG(gCredentialManagerSecretLog, - LogLevel::Debug, - ("CredReadA failed %d", GetLastError())); - return NS_ERROR_FAILURE; - } - MOZ_ASSERT(pcred); - aSecret.Assign(reinterpret_cast(pcred->CredentialBlob), - pcred->CredentialBlobSize); - return NS_OK; -} diff --git a/security/manager/ssl/CredentialManagerSecret.h b/security/manager/ssl/CredentialManagerSecret.h deleted file mode 100644 index b31aeac45bee..000000000000 --- a/security/manager/ssl/CredentialManagerSecret.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CredentialManagerSecret_h -#define CredentialManagerSecret_h - -#include "OSKeyStore.h" -#include "nsString.h" - -class CredentialManagerSecret final : public AbstractOSKeyStore -{ -public: - CredentialManagerSecret(); - - virtual nsresult RetrieveSecret(const nsACString& label, - /* out */ nsACString& secret) override; - virtual nsresult StoreSecret(const nsACString& secret, - const nsACString& label) override; - virtual nsresult DeleteSecret(const nsACString& label) override; - virtual nsresult Lock() override; - virtual nsresult Unlock() override; - - virtual ~CredentialManagerSecret(); -}; - -#endif // CredentialManagerSecret_h diff --git a/security/manager/ssl/OSKeyStore.cpp b/security/manager/ssl/OSKeyStore.cpp index 350454a81479..fc2eb4fb2c75 100644 --- a/security/manager/ssl/OSKeyStore.cpp +++ b/security/manager/ssl/OSKeyStore.cpp @@ -15,8 +15,6 @@ #include "LibSecret.h" #elif defined(XP_MACOSX) #include "KeychainSecret.h" -#elif defined(XP_WIN) -#include "CredentialManagerSecret.h" #else #include "NSSKeyStore.h" #endif @@ -35,8 +33,6 @@ OSKeyStore::OSKeyStore() mKs.reset(new LibSecret()); #elif defined(XP_MACOSX) mKs.reset(new KeychainSecret()); -#elif defined(XP_WIN) - mKs.reset(new CredentialManagerSecret()); #else mKs.reset(new NSSKeyStore()); #endif diff --git a/security/manager/ssl/moz.build b/security/manager/ssl/moz.build index 3eb9ae6a469a..2fdea5b11caf 100644 --- a/security/manager/ssl/moz.build +++ b/security/manager/ssl/moz.build @@ -155,11 +155,6 @@ if CONFIG['OS_ARCH'] == 'Darwin': '-framework Security' ] -if CONFIG['OS_ARCH'] == 'WINNT': - UNIFIED_SOURCES += [ - 'CredentialManagerSecret.cpp', - ] - IPDL_SOURCES += [ 'PPSMContentDownloader.ipdl', ] diff --git a/security/manager/ssl/tests/unit/test_oskeystore.js b/security/manager/ssl/tests/unit/test_oskeystore.js index 1df729a317d9..3ebec65810b4 100644 --- a/security/manager/ssl/tests/unit/test_oskeystore.js +++ b/security/manager/ssl/tests/unit/test_oskeystore.js @@ -15,7 +15,8 @@ const LABELS = ["mylabel1", async function delete_all_secrets() { let keystore = Cc["@mozilla.org/security/oskeystore;1"] .getService(Ci.nsIOSKeyStore); - for (let label of LABELS) { + for (let i in LABELS) { + let label = LABELS[i]; if (await keystore.asyncSecretAvailable(label)) { await keystore.asyncDeleteSecret(label); ok(!await keystore.asyncSecretAvailable(label), label + " should be deleted now."); @@ -113,8 +114,8 @@ add_task(async function() { await encrypt_decrypt_test(); await delete_all_secrets(); - if (AppConstants.platform == "macosx" || AppConstants.platform == "win") { - ok(!keystore.isNSSKeyStore, "OS X and Windows should use the non-NSS implementation"); + if (AppConstants.platform == "macosx") { + ok(!keystore.isNSSKeyStore, "OS X should use the non-NSS implementation"); } if (keystore.isNSSKeyStore) { From 0fb02494afb40120b42879a6ba03e720dadebc0e Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Fri, 27 Jul 2018 18:52:21 +0200 Subject: [PATCH 07/52] Bug 1454627 - Re-enable browser_ext_user_events.js (bug 1381305) r=mixedpuppy Re-enable the test that was disabled in bug 1381305 and fix the underlying issue that caused th intermittent failure in the first place. MozReview-Commit-ID: BL9wS2fogaf --HG-- extra : rebase_source : 685f43b2e47d80f71814385a5c8b94fd3000eac9 --- .../extensions/test/browser/browser-common.ini | 1 - .../test/browser/browser_ext_user_events.js | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/browser/components/extensions/test/browser/browser-common.ini b/browser/components/extensions/test/browser/browser-common.ini index 4e6952b4a412..fad6f5761ffb 100644 --- a/browser/components/extensions/test/browser/browser-common.ini +++ b/browser/components/extensions/test/browser/browser-common.ini @@ -210,7 +210,6 @@ skip-if = os == 'mac' # Save as PDF not supported on Mac OS X [browser_ext_themes_validation.js] [browser_ext_url_overrides_newtab.js] [browser_ext_user_events.js] -skip-if = debug || os == "linux" #Bug 1381305 [browser_ext_webRequest.js] [browser_ext_webNavigation_frameId0.js] [browser_ext_webNavigation_getFrames.js] diff --git a/browser/components/extensions/test/browser/browser_ext_user_events.js b/browser/components/extensions/test/browser/browser_ext_user_events.js index 0c95b6a41694..f86011361759 100644 --- a/browser/components/extensions/test/browser/browser_ext_user_events.js +++ b/browser/components/extensions/test/browser/browser_ext_user_events.js @@ -47,12 +47,6 @@ add_task(async function testSources() { browser.pageAction.onClicked.addListener(() => request("bookmarks")); browser.browserAction.onClicked.addListener(() => request("tabs")); - - browser.contextMenus.create({ - id: "menu", - title: "test user events", - contexts: ["page"], - }); browser.contextMenus.onClicked.addListener(() => request("webNavigation")); browser.test.onMessage.addListener(msg => { @@ -61,7 +55,13 @@ add_task(async function testSources() { } }); - browser.test.sendMessage("actions-ready"); + browser.contextMenus.create({ + id: "menu", + title: "test user events", + contexts: ["page"], + }, () => { + browser.test.sendMessage("actions-ready"); + }); }, files: { From c7c432f91ab24456970dc34be8fcc32e6d3c3be3 Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Fri, 27 Jul 2018 19:06:00 +0200 Subject: [PATCH 08/52] Bug 1454627 - Run "onclick" event of menu with user input r=mixedpuppy MozReview-Commit-ID: r1URJfOKUB --HG-- extra : rebase_source : 1f5c5bb7b6dbd9709a26bf10abddcda919eff70f --- .../components/extensions/child/ext-menus.js | 2 +- .../test/browser/browser_ext_user_events.js | 27 +++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/browser/components/extensions/child/ext-menus.js b/browser/components/extensions/child/ext-menus.js index ef8afcbaf3da..ee204036e9a9 100644 --- a/browser/components/extensions/child/ext-menus.js +++ b/browser/components/extensions/child/ext-menus.js @@ -32,7 +32,7 @@ class ContextMenusClickPropHandler { // No need for runSafe or anything because we are already being run inside // an event handler -- the event is just being forwarded to the actual // handler. - onclick(info, tab); + withHandlingUserInput(this.context.contentWindow, () => onclick(info, tab)); } } diff --git a/browser/components/extensions/test/browser/browser_ext_user_events.js b/browser/components/extensions/test/browser/browser_ext_user_events.js index f86011361759..55b30d31e3f8 100644 --- a/browser/components/extensions/test/browser/browser_ext_user_events.js +++ b/browser/components/extensions/test/browser/browser_ext_user_events.js @@ -47,9 +47,15 @@ add_task(async function testSources() { browser.pageAction.onClicked.addListener(() => request("bookmarks")); browser.browserAction.onClicked.addListener(() => request("tabs")); - browser.contextMenus.onClicked.addListener(() => request("webNavigation")); browser.test.onMessage.addListener(msg => { + if (msg === "contextMenus.update") { + browser.contextMenus.onClicked.addListener(() => request("webNavigation")); + browser.contextMenus.update("menu", { + title: "test user events in onClicked", + onclick: null, + }, () => browser.test.sendMessage("contextMenus.update-done")); + } if (msg === "openOptionsPage") { browser.runtime.openOptionsPage(); } @@ -57,8 +63,11 @@ add_task(async function testSources() { browser.contextMenus.create({ id: "menu", - title: "test user events", + title: "test user events in onclick", contexts: ["page"], + onclick() { + request("cookies"); + }, }, () => { browser.test.sendMessage("actions-ready"); }); @@ -111,7 +120,7 @@ add_task(async function testSources() { browser_action: {default_title: "test"}, page_action: {default_title: "test"}, permissions: ["contextMenus"], - optional_permissions: ["bookmarks", "tabs", "webNavigation", "webRequest"], + optional_permissions: ["bookmarks", "tabs", "webNavigation", "webRequest", "cookies"], options_ui: {page: "options.html"}, content_security_policy: "script-src 'self' https://example.com; object-src 'none';", }, @@ -153,10 +162,18 @@ add_task(async function testSources() { gBrowser.selectedTab = tab; let menu = await openContextMenu("body"); - let items = menu.getElementsByAttribute("label", "test user events"); + let items = menu.getElementsByAttribute("label", "test user events in onclick"); is(items.length, 1, "Found context menu item"); EventUtils.synthesizeMouseAtCenter(items[0], {}); - await check("context menu click"); + await check("context menu in onclick"); + + extension.sendMessage("contextMenus.update"); + await extension.awaitMessage("contextMenus.update-done"); + menu = await openContextMenu("body"); + items = menu.getElementsByAttribute("label", "test user events in onClicked"); + is(items.length, 1, "Found context menu item again"); + EventUtils.synthesizeMouseAtCenter(items[0], {}); + await check("context menu in onClicked"); extension.sendMessage("openOptionsPage"); promisePopupNotificationShown("addon-webext-permissions").then(panel => { From 6fd8625b0481a5c38f7fa0a29545a4cb386d8d39 Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Tue, 31 Jul 2018 16:58:41 +0200 Subject: [PATCH 09/52] Bug 1454627 - Fix timing issue in browser_ext_user_events.js r=mixedpuppy The hard-coded wait exists to avoid a test failure caused by a non-functional click event in an options browser. However, that still does not get rid of the intermittent failure. To really avoid the timing issue, check whether onclick was fired after supposedly triggering a click, and if not, wait and retry. MozReview-Commit-ID: 9eg6sz1s1e3 --HG-- extra : rebase_source : 8945f2597beb99e9c5d03c08bc054692960e6281 --- .../test/browser/browser_ext_user_events.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/browser/components/extensions/test/browser/browser_ext_user_events.js b/browser/components/extensions/test/browser/browser_ext_user_events.js index 55b30d31e3f8..84bba4162fff 100644 --- a/browser/components/extensions/test/browser/browser_ext_user_events.js +++ b/browser/components/extensions/test/browser/browser_ext_user_events.js @@ -90,8 +90,11 @@ add_task(async function testSources() { addEventListener("load", async () => { let link = document.getElementById("link"); link.onclick = async event => { + link.onclick = null; event.preventDefault(); + browser.test.log("Calling permission.request from options page."); + try { let result = await browser.permissions.request({ permissions: ["webRequest"], @@ -107,12 +110,12 @@ add_task(async function testSources() { // we don't really have a reliable way to detect this from the // options page side, and synthetic click events won't work // until it is. - for (let i = 0; i < 10; i++) { + do { + browser.test.log("Waiting for the options browser to be visible..."); await new Promise(resolve => setTimeout(resolve, 0)); - } - - synthesizeMouseAtCenter(link, {}); - }, {once: true}); + synthesizeMouseAtCenter(link, {}); + } while (link.onclick !== null); + }); }, }, @@ -175,10 +178,10 @@ add_task(async function testSources() { EventUtils.synthesizeMouseAtCenter(items[0], {}); await check("context menu in onClicked"); - extension.sendMessage("openOptionsPage"); promisePopupNotificationShown("addon-webext-permissions").then(panel => { panel.button.click(); }); + extension.sendMessage("openOptionsPage"); await check("options page link click"); await BrowserTestUtils.removeTab(gBrowser.selectedTab); From e6061725f91fb97963a7feb63b3da25ccd84d026 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 1 Aug 2018 09:34:59 +0000 Subject: [PATCH 10/52] Bug 1478668 - windows key store adapter, r=keeler OS key-store adapter for Windows Credential Manager. It looks like Windows doesn't allow locking the credential manager without locking the desktop. So `lock` and `unlock` are no-ops here. Depends on D2487. Differential Revision: https://phabricator.services.mozilla.com/D2550 --HG-- extra : moz-landing-system : lando --- .../manager/ssl/CredentialManagerSecret.cpp | 129 ++++++++++++++++++ .../manager/ssl/CredentialManagerSecret.h | 29 ++++ security/manager/ssl/OSKeyStore.cpp | 4 + security/manager/ssl/moz.build | 5 + .../manager/ssl/tests/unit/test_oskeystore.js | 7 +- 5 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 security/manager/ssl/CredentialManagerSecret.cpp create mode 100644 security/manager/ssl/CredentialManagerSecret.h diff --git a/security/manager/ssl/CredentialManagerSecret.cpp b/security/manager/ssl/CredentialManagerSecret.cpp new file mode 100644 index 000000000000..75e90b82a7f9 --- /dev/null +++ b/security/manager/ssl/CredentialManagerSecret.cpp @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CredentialManagerSecret.h" + +#include +#include + +#include "mozilla/Logging.h" +#include "mozilla/SyncRunnable.h" + +// This is the implementation of CredentialManagerSecretSecret, an instantiation +// of OSKeyStore for Windows. It uses the system credential manager, hence the +// name. + +using namespace mozilla; + +LazyLogModule gCredentialManagerSecretLog("credentialmanagersecret"); +struct ScopedDelete +{ + void operator()(CREDENTIALA* cred) { CredFree(cred); } +}; + +template +struct ScopedMaybeDelete +{ + void operator()(T* ptr) + { + if (ptr) { + ScopedDelete del; + del(ptr); + } + } +}; +typedef std::unique_ptr> ScopedCREDENTIALA; + +CredentialManagerSecret::CredentialManagerSecret() {} + +CredentialManagerSecret::~CredentialManagerSecret() {} + +nsresult +CredentialManagerSecret::Lock() +{ + // The Windows credential manager can't be locked. + return NS_OK; +} + +nsresult +CredentialManagerSecret::Unlock() +{ + // The Windows credential manager is always unlocked when the user is logged + // in. + return NS_OK; +} + +nsresult +CredentialManagerSecret::StoreSecret(const nsACString& aSecret, + const nsACString& aLabel) +{ + if (aSecret.Length() > CRED_MAX_CREDENTIAL_BLOB_SIZE) { + // Windows doesn't allow blobs larger than CRED_MAX_CREDENTIAL_BLOB_SIZE + // bytes. + MOZ_LOG(gCredentialManagerSecretLog, + LogLevel::Debug, + ("StoreSecret secret must not be larger than 512 bytes (got %d)", + aSecret.Length())); + return NS_ERROR_FAILURE; + } + CREDENTIALA cred = { 0 }; + cred.Type = CRED_TYPE_GENERIC; + const nsCString& label = PromiseFlatCString(aLabel); + cred.TargetName = const_cast(label.get()); + cred.CredentialBlobSize = aSecret.Length(); + const nsCString& secret = PromiseFlatCString(aSecret); + cred.CredentialBlob = (LPBYTE)secret.get(); + cred.Persist = CRED_PERSIST_LOCAL_MACHINE; + cred.UserName = ""; + + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credwritea + BOOL ok = CredWriteA(&cred, 0); + if (!ok) { + MOZ_LOG(gCredentialManagerSecretLog, + LogLevel::Debug, + ("CredWriteW failed %d", GetLastError())); + NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult +CredentialManagerSecret::DeleteSecret(const nsACString& aLabel) +{ + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creddeletea + const nsCString& label = PromiseFlatCString(aLabel); + BOOL ok = CredDeleteA(label.get(), CRED_TYPE_GENERIC, 0); + int error = GetLastError(); + if (!ok && error != ERROR_NOT_FOUND) { + MOZ_LOG(gCredentialManagerSecretLog, + LogLevel::Debug, + ("CredDeleteA failed %d", error)); + NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult +CredentialManagerSecret::RetrieveSecret(const nsACString& aLabel, + /* out */ nsACString& aSecret) +{ + aSecret.Truncate(); + PCREDENTIALA pcred_raw = nullptr; + const nsCString& label = PromiseFlatCString(aLabel); + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credreada + BOOL ok = CredReadA(label.get(), CRED_TYPE_GENERIC, 0, &pcred_raw); + ScopedCREDENTIALA pcred(pcred_raw); + if (!ok) { + MOZ_LOG(gCredentialManagerSecretLog, + LogLevel::Debug, + ("CredReadA failed %d", GetLastError())); + return NS_ERROR_FAILURE; + } + MOZ_ASSERT(pcred); + aSecret.Assign(reinterpret_cast(pcred->CredentialBlob), + pcred->CredentialBlobSize); + return NS_OK; +} diff --git a/security/manager/ssl/CredentialManagerSecret.h b/security/manager/ssl/CredentialManagerSecret.h new file mode 100644 index 000000000000..b31aeac45bee --- /dev/null +++ b/security/manager/ssl/CredentialManagerSecret.h @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CredentialManagerSecret_h +#define CredentialManagerSecret_h + +#include "OSKeyStore.h" +#include "nsString.h" + +class CredentialManagerSecret final : public AbstractOSKeyStore +{ +public: + CredentialManagerSecret(); + + virtual nsresult RetrieveSecret(const nsACString& label, + /* out */ nsACString& secret) override; + virtual nsresult StoreSecret(const nsACString& secret, + const nsACString& label) override; + virtual nsresult DeleteSecret(const nsACString& label) override; + virtual nsresult Lock() override; + virtual nsresult Unlock() override; + + virtual ~CredentialManagerSecret(); +}; + +#endif // CredentialManagerSecret_h diff --git a/security/manager/ssl/OSKeyStore.cpp b/security/manager/ssl/OSKeyStore.cpp index fc2eb4fb2c75..350454a81479 100644 --- a/security/manager/ssl/OSKeyStore.cpp +++ b/security/manager/ssl/OSKeyStore.cpp @@ -15,6 +15,8 @@ #include "LibSecret.h" #elif defined(XP_MACOSX) #include "KeychainSecret.h" +#elif defined(XP_WIN) +#include "CredentialManagerSecret.h" #else #include "NSSKeyStore.h" #endif @@ -33,6 +35,8 @@ OSKeyStore::OSKeyStore() mKs.reset(new LibSecret()); #elif defined(XP_MACOSX) mKs.reset(new KeychainSecret()); +#elif defined(XP_WIN) + mKs.reset(new CredentialManagerSecret()); #else mKs.reset(new NSSKeyStore()); #endif diff --git a/security/manager/ssl/moz.build b/security/manager/ssl/moz.build index 2fdea5b11caf..3eb9ae6a469a 100644 --- a/security/manager/ssl/moz.build +++ b/security/manager/ssl/moz.build @@ -155,6 +155,11 @@ if CONFIG['OS_ARCH'] == 'Darwin': '-framework Security' ] +if CONFIG['OS_ARCH'] == 'WINNT': + UNIFIED_SOURCES += [ + 'CredentialManagerSecret.cpp', + ] + IPDL_SOURCES += [ 'PPSMContentDownloader.ipdl', ] diff --git a/security/manager/ssl/tests/unit/test_oskeystore.js b/security/manager/ssl/tests/unit/test_oskeystore.js index 3ebec65810b4..1df729a317d9 100644 --- a/security/manager/ssl/tests/unit/test_oskeystore.js +++ b/security/manager/ssl/tests/unit/test_oskeystore.js @@ -15,8 +15,7 @@ const LABELS = ["mylabel1", async function delete_all_secrets() { let keystore = Cc["@mozilla.org/security/oskeystore;1"] .getService(Ci.nsIOSKeyStore); - for (let i in LABELS) { - let label = LABELS[i]; + for (let label of LABELS) { if (await keystore.asyncSecretAvailable(label)) { await keystore.asyncDeleteSecret(label); ok(!await keystore.asyncSecretAvailable(label), label + " should be deleted now."); @@ -114,8 +113,8 @@ add_task(async function() { await encrypt_decrypt_test(); await delete_all_secrets(); - if (AppConstants.platform == "macosx") { - ok(!keystore.isNSSKeyStore, "OS X should use the non-NSS implementation"); + if (AppConstants.platform == "macosx" || AppConstants.platform == "win") { + ok(!keystore.isNSSKeyStore, "OS X and Windows should use the non-NSS implementation"); } if (keystore.isNSSKeyStore) { From f55e636331d05c1ec152f7d9bff3cc84da99a3df Mon Sep 17 00:00:00 2001 From: Luca Greco Date: Thu, 26 Jul 2018 13:53:22 +0200 Subject: [PATCH 11/52] Bug 1477015 - Select storage.local backend on startup when the extension is not migrating its data. r=aswan,mixedpuppy MozReview-Commit-ID: WzW2bFlYNg --HG-- extra : rebase_source : 048dbd36e6bf1bfc64d02e11bf26af1392071139 --- toolkit/components/extensions/Extension.jsm | 22 +++- .../extensions/ExtensionStorageIDB.jsm | 19 +++- .../extensions/child/ext-storage.js | 104 ++++++++++-------- .../extensions/parent/ext-storage.js | 49 +++++++-- .../test/xpcshell/test_ext_storage_tab.js | 33 ++++-- .../xpcshell/test_ext_storage_telemetry.js | 58 +++++++--- 6 files changed, 205 insertions(+), 80 deletions(-) diff --git a/toolkit/components/extensions/Extension.jsm b/toolkit/components/extensions/Extension.jsm index 3b0cdf850094..95fdb3bb8896 100644 --- a/toolkit/components/extensions/Extension.jsm +++ b/toolkit/components/extensions/Extension.jsm @@ -44,6 +44,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm", ExtensionPermissions: "resource://gre/modules/ExtensionPermissions.jsm", ExtensionStorage: "resource://gre/modules/ExtensionStorage.jsm", + ExtensionStorageIDB: "resource://gre/modules/ExtensionStorageIDB.jsm", ExtensionTestCommon: "resource://testing-common/ExtensionTestCommon.jsm", FileSource: "resource://gre/modules/L10nRegistry.jsm", L10nRegistry: "resource://gre/modules/L10nRegistry.jsm", @@ -147,7 +148,6 @@ const LOGGER_ID_BASE = "addons.webextension."; const UUID_MAP_PREF = "extensions.webextensions.uuids"; const LEAVE_STORAGE_PREF = "extensions.webextensions.keepStorageOnUninstall"; const LEAVE_UUID_PREF = "extensions.webextensions.keepUuidOnUninstall"; -const IDB_MIGRATED_PREF_BRANCH = "extensions.webextensions.ExtensionStorageIDB.migrated"; const COMMENT_REGEXP = new RegExp(String.raw` ^ @@ -252,8 +252,7 @@ var UninstallObserver = { }); Services.qms.clearStoragesForPrincipal(storagePrincipal); - // Clear the preference set for the extensions migrated to the IDBBackend. - Services.prefs.clearUserPref(`${IDB_MIGRATED_PREF_BRANCH}.${addon.id}`); + ExtensionStorageIDB.clearMigratedExtensionPref(addon.id); // Clear localStorage created by the extension let storage = Services.domStorageManager.getStorage(null, principal); @@ -1773,6 +1772,23 @@ class Extension extends ExtensionData { this.updatePermissions(this.startupReason); + // Select the storage.local backend if it is already known, + // and start the data migration if needed. + if (this.hasPermission("storage")) { + if (!ExtensionStorageIDB.isBackendEnabled) { + this.setSharedData("storageIDBBackend", false); + } else if (ExtensionStorageIDB.isMigratedExtension(this)) { + this.setSharedData("storageIDBBackend", true); + this.setSharedData("storageIDBPrincipal", ExtensionStorageIDB.getStoragePrincipal(this)); + } else { + // If the extension has to migrate backend, ensure that the data migration + // starts once Firefox is idle after the extension has been started. + this.once("ready", () => ChromeUtils.idleDispatch(() => { + ExtensionStorageIDB.selectBackend({extension: this}); + })); + } + } + // The "startup" Management event sent on the extension instance itself // is emitted just before the Management "startup" event, // and it is used to run code that needs to be executed before diff --git a/toolkit/components/extensions/ExtensionStorageIDB.jsm b/toolkit/components/extensions/ExtensionStorageIDB.jsm index 18de03984636..ff163818c5ab 100644 --- a/toolkit/components/extensions/ExtensionStorageIDB.jsm +++ b/toolkit/components/extensions/ExtensionStorageIDB.jsm @@ -373,8 +373,7 @@ async function migrateJSONFileData(extension, storagePrincipal) { let dataMigrateCompleted = false; let hasOldData = false; - const isMigratedExtension = Services.prefs.getBoolPref(`${IDB_MIGRATED_PREF_BRANCH}.${extension.id}`, false); - if (isMigratedExtension) { + if (ExtensionStorageIDB.isMigratedExtension(extension)) { return; } @@ -387,7 +386,7 @@ async function migrateJSONFileData(extension, storagePrincipal) { // there is no "going back": any data that has not been migrated will be still on disk // but it is not going to be migrated anymore, it could be eventually used to allow // a user to manually retrieve the old data file). - Services.prefs.setBoolPref(`${IDB_MIGRATED_PREF_BRANCH}.${extension.id}`, true); + ExtensionStorageIDB.setMigratedExtensionPref(extension, true); return; } } catch (err) { @@ -485,7 +484,7 @@ async function migrateJSONFileData(extension, storagePrincipal) { } } - Services.prefs.setBoolPref(`${IDB_MIGRATED_PREF_BRANCH}.${extension.id}`, true); + ExtensionStorageIDB.setMigratedExtensionPref(extension, true); DataMigrationTelemetry.recordResult({ backend: "IndexedDB", @@ -521,6 +520,18 @@ this.ExtensionStorageIDB = { XPCOMUtils.defineLazyPreferenceGetter(this, "isBackendEnabled", BACKEND_ENABLED_PREF, false); }, + isMigratedExtension(extension) { + return Services.prefs.getBoolPref(`${IDB_MIGRATED_PREF_BRANCH}.${extension.id}`, false); + }, + + setMigratedExtensionPref(extension, val) { + Services.prefs.setBoolPref(`${IDB_MIGRATED_PREF_BRANCH}.${extension.id}`, !!val); + }, + + clearMigratedExtensionPref(extensionId) { + Services.prefs.clearUserPref(`${IDB_MIGRATED_PREF_BRANCH}.${extensionId}`); + }, + getStoragePrincipal(extension) { return extension.createPrincipal(extension.baseURI, { userContextId: WEBEXT_STORAGE_USER_CONTEXT_ID, diff --git a/toolkit/components/extensions/child/ext-storage.js b/toolkit/components/extensions/child/ext-storage.js index 0cf733f5647f..342cb1845a3a 100644 --- a/toolkit/components/extensions/child/ext-storage.js +++ b/toolkit/components/extensions/child/ext-storage.js @@ -4,6 +4,8 @@ ChromeUtils.defineModuleGetter(this, "ExtensionStorage", "resource://gre/modules/ExtensionStorage.jsm"); ChromeUtils.defineModuleGetter(this, "ExtensionStorageIDB", "resource://gre/modules/ExtensionStorageIDB.jsm"); +ChromeUtils.defineModuleGetter(this, "Services", + "resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch", "resource://gre/modules/TelemetryStopwatch.jsm"); @@ -55,7 +57,7 @@ this.storage = class extends ExtensionAPI { }; } - getLocalIDBBackend(context, {hasParentListeners, serialize, storagePrincipal}) { + getLocalIDBBackend(context, {fireOnChanged, serialize, storagePrincipal}) { let dbPromise; async function getDB() { if (dbPromise) { @@ -86,14 +88,8 @@ this.storage = class extends ExtensionAPI { serialize: ExtensionStorage.serialize, }); - if (!changes) { - return; - } - - const hasListeners = await hasParentListeners(); - if (hasListeners) { - await context.childManager.callParentAsyncFunction( - "storage.local.IDBBackend.fireOnChanged", [changes]); + if (changes) { + fireOnChanged(changes); } }); }, @@ -101,34 +97,23 @@ this.storage = class extends ExtensionAPI { const db = await getDB(); const changes = await db.remove(keys); - if (!changes) { - return; - } - - const hasListeners = await hasParentListeners(); - if (hasListeners) { - await context.childManager.callParentAsyncFunction( - "storage.local.IDBBackend.fireOnChanged", [changes]); + if (changes) { + fireOnChanged(changes); } }, async clear() { const db = await getDB(); const changes = await db.clear(context.extension); - if (!changes) { - return; - } - - const hasListeners = await hasParentListeners(); - if (hasListeners) { - await context.childManager.callParentAsyncFunction( - "storage.local.IDBBackend.fireOnChanged", [changes]); + if (changes) { + fireOnChanged(changes); } }, }; } getAPI(context) { + const {extension} = context; const serialize = ExtensionStorage.serializeForContext.bind(null, context); const deserialize = ExtensionStorage.deserializeForContext.bind(null, context); @@ -152,9 +137,17 @@ this.storage = class extends ExtensionAPI { return sanitized; } - // Detect the actual storage.local enabled backend for the extension (as soon as the - // storage.local API has been accessed for the first time). - let promiseStorageLocalBackend; + function fireOnChanged(changes) { + // This call is used (by the storage.local API methods for the IndexedDB backend) to fire a storage.onChanged event, + // it uses the underlying message manager since the child context (or its ProxyContentParent counterpart + // running in the main process) may be gone by the time we call this, and so we can't use the childManager + // abstractions (e.g. callParentAsyncFunction or callParentFunctionNoReturn). + Services.cpmm.sendAsyncMessage(`Extension:StorageLocalOnChanged:${extension.uuid}`, changes); + } + + // If the selected backend for the extension is not known yet, we have to lazily detect it + // by asking to the main process (as soon as the storage.local API has been accessed for + // the first time). const getStorageLocalBackend = async () => { const { backendEnabled, @@ -167,33 +160,58 @@ this.storage = class extends ExtensionAPI { return this.getLocalIDBBackend(context, { storagePrincipal, - hasParentListeners() { - // We spare a good amount of memory if there are no listeners around - // (e.g. because they have never been subscribed or they have been removed - // in the meantime). - return context.childManager.callParentAsyncFunction( - "storage.local.IDBBackend.hasListeners", []); - }, + fireOnChanged, serialize, }); }; + // Synchronously select the backend if it is already known. + let selectedBackend; + + const useStorageIDBBackend = extension.getSharedData("storageIDBBackend"); + if (useStorageIDBBackend === false) { + selectedBackend = this.getLocalFileBackend(context, {deserialize, serialize}); + } else if (useStorageIDBBackend === true) { + selectedBackend = this.getLocalIDBBackend(context, { + storagePrincipal: extension.getSharedData("storageIDBPrincipal"), + fireOnChanged, + serialize, + }); + } + + let promiseStorageLocalBackend; + // Generate the backend-agnostic local API wrapped methods. const local = {}; for (let method of ["get", "set", "remove", "clear"]) { local[method] = async function(...args) { try { - if (!promiseStorageLocalBackend) { - promiseStorageLocalBackend = getStorageLocalBackend(); + // Discover the selected backend if it is not known yet. + if (!selectedBackend) { + if (!promiseStorageLocalBackend) { + promiseStorageLocalBackend = getStorageLocalBackend().catch(err => { + // Clear the cached promise if it has been rejected. + promiseStorageLocalBackend = null; + throw err; + }); + } + + // If the storage.local method is not 'get' (which doesn't change any of the stored data), + // fall back to call the method in the parent process, so that it can be completed even + // if this context has been destroyed in the meantime. + if (method !== "get") { + // Let the outer try to catch rejections returned by the backend methods. + const result = await context.childManager.callParentAsyncFunction( + "storage.local.callMethodInParentProcess", [method, args]); + return result; + } + + // Get the selected backend and cache it for the next API calls from this context. + selectedBackend = await promiseStorageLocalBackend; } - const backend = await promiseStorageLocalBackend.catch(err => { - // Clear the cached promise if it has been rejected. - promiseStorageLocalBackend = null; - throw err; - }); // Let the outer try to catch rejections returned by the backend methods. - const result = await backend[method](...args); + const result = await selectedBackend[method](...args); return result; } catch (err) { // Ensure that the error we throw is converted into an ExtensionError diff --git a/toolkit/components/extensions/parent/ext-storage.js b/toolkit/components/extensions/parent/ext-storage.js index e7162a5d64df..c95064b9e168 100644 --- a/toolkit/components/extensions/parent/ext-storage.js +++ b/toolkit/components/extensions/parent/ext-storage.js @@ -34,12 +34,52 @@ const lookupManagedStorage = async (extensionId, context) => { }; this.storage = class extends ExtensionAPI { + constructor(extension) { + super(extension); + + const messageName = `Extension:StorageLocalOnChanged:${extension.uuid}`; + Services.ppmm.addMessageListener(messageName, this); + this.clearStorageChangedListener = () => { + Services.ppmm.removeMessageListener(messageName, this); + }; + } + + onShutdown() { + const {clearStorageChangedListener} = this; + this.clearStorageChangedListener = null; + + if (clearStorageChangedListener) { + clearStorageChangedListener(); + } + } + + receiveMessage({name, data}) { + if (name !== `Extension:StorageLocalOnChanged:${this.extension.uuid}`) { + return; + } + + ExtensionStorageIDB.notifyListeners(this.extension.id, data); + } + getAPI(context) { let {extension} = context; return { storage: { local: { + async callMethodInParentProcess(method, args) { + const res = await ExtensionStorageIDB.selectBackend({extension}); + if (!res.backendEnabled) { + return ExtensionStorage[method](extension.id, ...args); + } + + const db = await ExtensionStorageIDB.open(res.storagePrincipal.deserialize(this)); + const changes = await db[method](...args); + if (changes) { + ExtensionStorageIDB.notifyListeners(extension.id, changes); + } + return changes; + }, // Private storage.local JSONFile backend methods (used internally by the child // ext-storage.js module). JSONFileBackend: { @@ -62,15 +102,6 @@ this.storage = class extends ExtensionAPI { selectBackend() { return ExtensionStorageIDB.selectBackend(context); }, - hasListeners() { - return ExtensionStorageIDB.hasListeners(extension.id); - }, - fireOnChanged(changes) { - ExtensionStorageIDB.notifyListeners(extension.id, changes); - }, - onceDataMigrated() { - return ExtensionStorageIDB.onceDataMigrated(context); - }, }, }, diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_storage_tab.js b/toolkit/components/extensions/test/xpcshell/test_ext_storage_tab.js index c1f15ab2ea6d..57e099dfd390 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_storage_tab.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_storage_tab.js @@ -104,6 +104,15 @@ add_task(async function test_storage_local_idb_backend_from_tab() { async function test_storage_local_call_from_destroying_context() { let extension = ExtensionTestUtils.loadExtension({ async background() { + let numberOfChanges = 0; + browser.storage.onChanged.addListener((changes, areaName) => { + if (areaName !== "local") { + browser.test.fail(`Received unexpected storage changes for "${areaName}"`); + } + + numberOfChanges++; + }); + browser.test.onMessage.addListener(async ({msg, values}) => { switch (msg) { case "storage-set": { @@ -116,6 +125,10 @@ async function test_storage_local_call_from_destroying_context() { browser.test.sendMessage("storage-get:done", res); break; } + case "storage-changes": { + browser.test.sendMessage("storage-changes-count", numberOfChanges); + break; + } default: browser.test.fail(`Received unexpected message: ${msg}`); } @@ -135,10 +148,8 @@ async function test_storage_local_call_from_destroying_context() { "tab.js"() { browser.test.log("Extension tab - calling storage.local API method"); // Call the storage.local API from a tab that is going to be quickly closed. - browser.storage.local.get({}).then(() => { - // This call should never be reached (because the tab should have been - // destroyed in the meantime). - browser.test.fail("Extension tab - Unexpected storage.local promise resolved"); + browser.storage.local.set({ + "test-key-from-destroying-context": "testvalue2", }); // Navigate away from the extension page, so that the storage.local API call will be unable // to send the call to the caller context (because it has been destroyed in the meantime). @@ -154,17 +165,25 @@ async function test_storage_local_call_from_destroying_context() { const url = await extension.awaitMessage("ext-page-url"); let contentPage = await ExtensionTestUtils.loadContentPage(url, {extension}); - let expectedData = {"test-key": "test-value"}; + let expectedBackgroundPageData = {"test-key-from-background-page": "test-value"}; + let expectedTabData = {"test-key-from-destroying-context": "testvalue2"}; info("Call storage.local.set from the background page and wait it to be completed"); - extension.sendMessage({msg: "storage-set", values: expectedData}); + extension.sendMessage({msg: "storage-set", values: expectedBackgroundPageData}); await extension.awaitMessage("storage-set:done"); info("Call storage.local.get from the background page and wait it to be completed"); extension.sendMessage({msg: "storage-get"}); let res = await extension.awaitMessage("storage-get:done"); - Assert.deepEqual(res, expectedData, "Got the expected data set in the storage.local backend"); + Assert.deepEqual(res, { + ...expectedBackgroundPageData, + ...expectedTabData, + }, "Got the expected data set in the storage.local backend"); + + extension.sendMessage({msg: "storage-changes"}); + equal(await extension.awaitMessage("storage-changes-count"), 2, + "Got the expected number of storage.onChanged event received"); contentPage.close(); diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_storage_telemetry.js b/toolkit/components/extensions/test/xpcshell/test_ext_storage_telemetry.js index 7feadb1cbf1c..58b6157b93c2 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_storage_telemetry.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_storage_telemetry.js @@ -14,6 +14,9 @@ const HISTOGRAM_IDB_IDS = [ const HISTOGRAM_IDS = [].concat(HISTOGRAM_JSON_IDS, HISTOGRAM_IDB_IDS); +const EXTENSION_ID1 = "@test-extension1"; +const EXTENSION_ID2 = "@test-extension2"; + async function test_telemetry_background() { const expectedEmptyHistograms = ExtensionStorageIDB.isBackendEnabled ? HISTOGRAM_JSON_IDS : HISTOGRAM_IDB_IDS; @@ -32,16 +35,17 @@ async function test_telemetry_background() { browser.runtime.sendMessage("contentDone"); } - let extInfo = { - manifest: { - permissions: ["storage"], - content_scripts: [ - { - "matches": ["http://*/*/file_sample.html"], - "js": ["content_script.js"], - }, - ], - }, + let baseManifest = { + permissions: ["storage"], + content_scripts: [ + { + "matches": ["http://*/*/file_sample.html"], + "js": ["content_script.js"], + }, + ], + }; + + let baseExtInfo = { async background() { browser.runtime.onMessage.addListener(msg => { browser.test.sendMessage(msg); @@ -56,8 +60,27 @@ async function test_telemetry_background() { }, }; - let extension1 = ExtensionTestUtils.loadExtension(extInfo); - let extension2 = ExtensionTestUtils.loadExtension(extInfo); + let extInfo1 = { + ...baseExtInfo, + manifest: { + ...baseManifest, + applications: { + gecko: {id: EXTENSION_ID1}, + }, + }, + }; + let extInfo2 = { + ...baseExtInfo, + manifest: { + ...baseManifest, + applications: { + gecko: {id: EXTENSION_ID2}, + }, + }, + }; + + let extension1 = ExtensionTestUtils.loadExtension(extInfo1); + let extension2 = ExtensionTestUtils.loadExtension(extInfo2); clearHistograms(); @@ -129,6 +152,13 @@ add_task(function test_telemetry_background_file_backend() { }); add_task(function test_telemetry_background_idb_backend() { - return runWithPrefs([[ExtensionStorageIDB.BACKEND_ENABLED_PREF, true]], - test_telemetry_background); + return runWithPrefs([ + [ExtensionStorageIDB.BACKEND_ENABLED_PREF, true], + // Set the migrated preference for the two test extension, because the + // first storage.local call fallbacks to run in the parent process when we + // don't know which is the selected backend during the extension startup + // and so we can't choose the telemetry histogram to use. + [`${ExtensionStorageIDB.IDB_MIGRATED_PREF_BRANCH}.${EXTENSION_ID1}`, true], + [`${ExtensionStorageIDB.IDB_MIGRATED_PREF_BRANCH}.${EXTENSION_ID2}`, true], + ], test_telemetry_background); }); From f1731211b56b78fa4a866cbb09a1ecccbf06801b Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Wed, 1 Aug 2018 10:13:59 +0000 Subject: [PATCH 12/52] Bug 1479722 - Rework PlacesUtils.setCharsetForURI to PlacesUIUtils.setCharsetForPage and avoid main thread sync io. r=mak MozReview-Commit-ID: HeO3Mm5Dibo Differential Revision: https://phabricator.services.mozilla.com/D2582 --HG-- extra : moz-landing-system : lando --- browser/base/content/browser-places.js | 5 +- browser/base/content/browser.js | 6 +- browser/components/places/PlacesUIUtils.jsm | 26 +++++ .../places/content/bookmarkProperties.js | 5 +- .../tests/unit/test_PUIU_setCharsetForPage.js | 101 ++++++++++++++++++ .../components/places/tests/unit/xpcshell.ini | 1 + toolkit/components/places/Bookmarks.jsm | 14 ++- toolkit/components/places/PlacesUtils.jsm | 25 ----- .../places/tests/bookmarks/test_1129529.js | 8 +- .../places/tests/unit/test_317472.js | 65 ----------- .../test_bookmarks_html_escape_entities.js | 8 +- .../tests/unit/test_promiseBookmarksTree.js | 5 +- .../components/places/tests/unit/xpcshell.ini | 1 - 13 files changed, 161 insertions(+), 109 deletions(-) create mode 100644 browser/components/places/tests/unit/test_PUIU_setCharsetForPage.js delete mode 100644 toolkit/components/places/tests/unit/test_317472.js diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js index c1011fc93fbc..90c9526d3caf 100644 --- a/browser/base/content/browser-places.js +++ b/browser/base/content/browser-places.js @@ -399,9 +399,8 @@ var PlacesCommandHook = { info.guid = await PlacesTransactions.NewBookmark(info).transact(); - // Set the character-set - if (charset && !PrivateBrowsingUtils.isBrowserPrivate(browser)) { - PlacesUtils.setCharsetForURI(makeURI(url.href), charset); + if (charset) { + PlacesUIUtils.setCharsetForPage(url, charset, window).catch(Cu.reportError); } } diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 7e87f5936089..06b751754389 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6225,8 +6225,9 @@ function BrowserSetForcedCharacterSet(aCharset) { if (aCharset) { gBrowser.selectedBrowser.characterSet = aCharset; // Save the forced character-set - if (!PrivateBrowsingUtils.isWindowPrivate(window)) - PlacesUtils.setCharsetForURI(getWebNavigation().currentURI, aCharset); + PlacesUIUtils.setCharsetForPage(getWebNavigation().currentURI, + aCharset, + window).catch(Cu.reportError); } BrowserCharsetReload(); } @@ -8244,4 +8245,3 @@ var ConfirmationHint = { return this._message = document.getElementById("confirmation-hint-message"); }, }; - diff --git a/browser/components/places/PlacesUIUtils.jsm b/browser/components/places/PlacesUIUtils.jsm index 974a7f0c8d78..6e89c9097074 100644 --- a/browser/components/places/PlacesUIUtils.jsm +++ b/browser/components/places/PlacesUIUtils.jsm @@ -459,6 +459,32 @@ var PlacesUIUtils = { PlacesUtils.history.markPageAsFollowedLink(this.createFixedURI(aURL)); }, + /** + * Sets the character-set for a page. The character set will not be saved + * if the window is determined to be a private browsing window. + * + * @param {string|URL|nsIURI} url The URL of the page to set the charset on. + * @param {String} charset character-set value. + * @param {window} window The window that the charset is being set from. + * @return {Promise} + */ + async setCharsetForPage(url, charset, window) { + if (PrivateBrowsingUtils.isWindowPrivate(window)) { + return; + } + + // UTF-8 is the default. If we are passed the value then set it to null, + // to ensure any charset is removed from the database. + if (charset.toLowerCase() == "utf-8") { + charset = null; + } + + await PlacesUtils.history.update({ + url, + annotations: new Map([[PlacesUtils.CHARSET_ANNO, charset]]) + }); + }, + /** * Allows opening of javascript/data URI only if the given node is * bookmarked (see bug 224521). diff --git a/browser/components/places/content/bookmarkProperties.js b/browser/components/places/content/bookmarkProperties.js index 46e9638f0486..a6e5862ef7f5 100644 --- a/browser/components/places/content/bookmarkProperties.js +++ b/browser/components/places/content/bookmarkProperties.js @@ -468,8 +468,9 @@ var BookmarkPropertiesPanel = { if (this._postData) info.postData = this._postData; - if (this._charSet && !PrivateBrowsingUtils.isWindowPrivate(window)) - PlacesUtils.setCharsetForURI(this._uri, this._charSet); + if (this._charSet) { + PlacesUIUtils.setCharsetForPage(this._uri, this._charSet, window).catch(Cu.reportError); + } itemGuid = await PlacesTransactions.NewBookmark(info).transact(); } else if (this._itemType == LIVEMARK_CONTAINER) { diff --git a/browser/components/places/tests/unit/test_PUIU_setCharsetForPage.js b/browser/components/places/tests/unit/test_PUIU_setCharsetForPage.js new file mode 100644 index 000000000000..3a0e414f48a7 --- /dev/null +++ b/browser/components/places/tests/unit/test_PUIU_setCharsetForPage.js @@ -0,0 +1,101 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* 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 {PrivateBrowsingUtils} = + ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm", {}); + +const UTF8 = "UTF-8"; +const UTF16 = "UTF-16"; +const CHARSET_ANNO = PlacesUtils.CHARSET_ANNO; + +const TEST_URI = "http://foo.com"; +const TEST_BOOKMARKED_URI = "http://bar.com"; + +add_task(function setup() { + let savedIsWindowPrivateFunc = PrivateBrowsingUtils.isWindowPrivate; + PrivateBrowsingUtils.isWindowPrivate = () => false; + + registerCleanupFunction(() => { + PrivateBrowsingUtils.isWindowPrivate = savedIsWindowPrivateFunc; + }); +}); + +add_task(async function test_simple_add() { + // add pages to history + await PlacesTestUtils.addVisits(TEST_URI); + await PlacesTestUtils.addVisits(TEST_BOOKMARKED_URI); + + // create bookmarks on TEST_BOOKMARKED_URI + await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + url: TEST_BOOKMARKED_URI, + title: TEST_BOOKMARKED_URI.spec, + }); + await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + url: TEST_BOOKMARKED_URI, + title: TEST_BOOKMARKED_URI.spec, + }); + + // set charset on not-bookmarked page + await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF16, {}); + // set charset on bookmarked page + await PlacesUIUtils.setCharsetForPage(TEST_BOOKMARKED_URI, UTF16, {}); + + let pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true}); + Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), UTF16, + "Should return correct charset for a not-bookmarked page"); + + pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, {includeAnnotations: true}); + Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), UTF16, + "Should return correct charset for a bookmarked page"); + + await PlacesUtils.history.clear(); + + pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true}); + Assert.ok(!pageInfo, "Should not return pageInfo for a page after history cleared"); + + pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, {includeAnnotations: true}); + Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), UTF16, + "Charset should still be set for a bookmarked page after history clear"); + + await PlacesUIUtils.setCharsetForPage(TEST_BOOKMARKED_URI, ""); + pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, {includeAnnotations: true}); + Assert.strictEqual(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), undefined, + "Should not have a charset after it has been removed from the page"); +}); + +add_task(async function test_utf8_clears_saved_anno() { + await PlacesUtils.history.clear(); + await PlacesTestUtils.addVisits(TEST_URI); + + // set charset on bookmarked page + await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF16, {}); + + let pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true}); + Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), UTF16, + "Should return correct charset for a not-bookmarked page"); + + // Now set the bookmark to a UTF-8 charset. + await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF8, {}); + + pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true}); + Assert.strictEqual(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), undefined, + "Should have removed the charset for a UTF-8 page."); +}); + +add_task(async function test_private_browsing_not_saved() { + await PlacesUtils.history.clear(); + await PlacesTestUtils.addVisits(TEST_URI); + + // set charset on bookmarked page, but pretend this is a private browsing window. + PrivateBrowsingUtils.isWindowPrivate = () => true; + await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF16, {}); + + let pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true}); + Assert.strictEqual(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), undefined, + "Should not have set the charset in a private browsing window."); +}); diff --git a/browser/components/places/tests/unit/xpcshell.ini b/browser/components/places/tests/unit/xpcshell.ini index 737136e9c38e..d0041c80918d 100644 --- a/browser/components/places/tests/unit/xpcshell.ini +++ b/browser/components/places/tests/unit/xpcshell.ini @@ -18,3 +18,4 @@ support-files = [test_browserGlue_restore.js] [test_clearHistory_shutdown.js] [test_PUIU_batchUpdatesForNode.js] +[test_PUIU_setCharsetForPage.js] diff --git a/toolkit/components/places/Bookmarks.jsm b/toolkit/components/places/Bookmarks.jsm index 7ffba6cdd89e..6b3b26c07a26 100644 --- a/toolkit/components/places/Bookmarks.jsm +++ b/toolkit/components/places/Bookmarks.jsm @@ -1395,7 +1395,7 @@ var Bookmarks = Object.freeze({ JOIN moz_bookmarks c ON c.parent = b.id WHERE p.guid = :tagsGuid GROUP BY name - ORDER BY name COLLATE nocase ASC + ORDER BY name COLLATE nocase ASC `, { tagsGuid: this.tagsGuid }); return rows.map(r => ({ name: r.getResultByName("name"), @@ -1947,7 +1947,17 @@ async function handleBookmarkItemSpecialData(itemId, item) { } if ("charset" in item && item.charset) { try { - await PlacesUtils.setCharsetForURI(NetUtil.newURI(item.url), item.charset); + // UTF-8 is the default. If we are passed the value then set it to null, + // to ensure any charset is removed from the database. + let charset = item.charset; + if (item.charset.toLowerCase() == "utf-8") { + charset = null; + } + + await PlacesUtils.history.update({ + url: item.url, + annotations: new Map([[PlacesUtils.CHARSET_ANNO, charset]]) + }); } catch (ex) { Cu.reportError(`Failed to set charset "${item.charset}" for ${item.url}: ${ex}`); } diff --git a/toolkit/components/places/PlacesUtils.jsm b/toolkit/components/places/PlacesUtils.jsm index fb33ff026eba..ea6728127afc 100644 --- a/toolkit/components/places/PlacesUtils.jsm +++ b/toolkit/components/places/PlacesUtils.jsm @@ -1484,31 +1484,6 @@ var PlacesUtils = { return db.executeBeforeShutdown(name, task); }, - /** - * Sets the character-set for a URI. - * - * @param {nsIURI} aURI - * @param {String} aCharset character-set value. - * @return {Promise} - */ - setCharsetForURI: function PU_setCharsetForURI(aURI, aCharset) { - return new Promise(resolve => { - // Delaying to catch issues with asynchronous behavior while waiting - // to implement asynchronous annotations in bug 699844. - Services.tm.dispatchToMainThread(function() { - if (aCharset && aCharset.length > 0) { - PlacesUtils.annotations.setPageAnnotation( - aURI, PlacesUtils.CHARSET_ANNO, aCharset, 0, - Ci.nsIAnnotationService.EXPIRE_NEVER); - } else { - PlacesUtils.annotations.removePageAnnotation( - aURI, PlacesUtils.CHARSET_ANNO); - } - resolve(); - }); - }); - }, - /** * Gets favicon data for a given page url. * diff --git a/toolkit/components/places/tests/bookmarks/test_1129529.js b/toolkit/components/places/tests/bookmarks/test_1129529.js index 19b209e98b2f..cb68467b6369 100644 --- a/toolkit/components/places/tests/bookmarks/test_1129529.js +++ b/toolkit/components/places/tests/bookmarks/test_1129529.js @@ -24,7 +24,7 @@ add_task(async function() { guid: "___guid1____", index: 0, id: 3, - charset: "UTF-8", + charset: "UTF-16", tags: "tag0", type: "text/x-moz-place", dateAdded: now, @@ -35,7 +35,7 @@ add_task(async function() { guid: "___guid2____", index: 1, id: 4, - charset: "UTF-8", + charset: "UTF-16", tags: "tag1,a" + "0123456789".repeat(10), // 101 chars type: "text/x-moz-place", dateAdded: now, @@ -46,7 +46,7 @@ add_task(async function() { guid: "___guid3____", index: 2, id: 5, - charset: "UTF-8", + charset: "UTF-16", tags: "tag2", type: "text/x-moz-place", dateAdded: now, @@ -67,7 +67,7 @@ add_task(async function() { for (let i = 0; i < unsortedBookmarks.length; ++i) { let bookmark = unsortedBookmarks[i]; - Assert.equal(bookmark.charset, "UTF-8"); + Assert.equal(bookmark.charset, "UTF-16"); Assert.equal(bookmark.dateAdded, now); Assert.equal(bookmark.lastModified, now); Assert.equal(bookmark.uri, "http://test" + i + ".com/"); diff --git a/toolkit/components/places/tests/unit/test_317472.js b/toolkit/components/places/tests/unit/test_317472.js deleted file mode 100644 index 8b6c7f4fe6f9..000000000000 --- a/toolkit/components/places/tests/unit/test_317472.js +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* 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 charset = "UTF-8"; -const CHARSET_ANNO = PlacesUtils.CHARSET_ANNO; - -const TEST_URI = uri("http://foo.com"); -const TEST_BOOKMARKED_URI = uri("http://bar.com"); - -add_task(async function test_execute() { - // add pages to history - await PlacesTestUtils.addVisits(TEST_URI); - await PlacesTestUtils.addVisits(TEST_BOOKMARKED_URI); - - // create bookmarks on TEST_BOOKMARKED_URI - await PlacesUtils.bookmarks.insert({ - parentGuid: PlacesUtils.bookmarks.unfiledGuid, - url: TEST_BOOKMARKED_URI, - title: TEST_BOOKMARKED_URI.spec, - }); - await PlacesUtils.bookmarks.insert({ - parentGuid: PlacesUtils.bookmarks.toolbarGuid, - url: TEST_BOOKMARKED_URI, - title: TEST_BOOKMARKED_URI.spec, - }); - - // set charset on not-bookmarked page - await PlacesUtils.setCharsetForURI(TEST_URI, charset); - // set charset on bookmarked page - await PlacesUtils.setCharsetForURI(TEST_BOOKMARKED_URI, charset); - - // check that we have created a page annotation - Assert.equal(PlacesUtils.annotations.getPageAnnotation(TEST_URI, CHARSET_ANNO), charset); - - let pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true}); - Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), charset, - "Should return correct charset for a not-bookmarked page"); - - pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, {includeAnnotations: true}); - Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), charset, - "Should return correct charset for a bookmarked page"); - - await PlacesUtils.history.clear(); - - pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true}); - Assert.ok(!pageInfo, "Should not return pageInfo for a page after history cleared"); - - // check that page annotation has been removed - try { - PlacesUtils.annotations.getPageAnnotation(TEST_URI, CHARSET_ANNO); - do_throw("Charset page annotation has not been removed correctly"); - } catch (e) {} - - pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, {includeAnnotations: true}); - Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), charset, - "Charset should still be set for a bookmarked page after history clear"); - - await PlacesUtils.setCharsetForURI(TEST_BOOKMARKED_URI, ""); - pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, {includeAnnotations: true}); - Assert.notEqual(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), charset, - "Should not have a charset after it has been removed from the page"); -}); diff --git a/toolkit/components/places/tests/unit/test_bookmarks_html_escape_entities.js b/toolkit/components/places/tests/unit/test_bookmarks_html_escape_entities.js index 0cb67c29f168..4e11e7c367a7 100644 --- a/toolkit/components/places/tests/unit/test_bookmarks_html_escape_entities.js +++ b/toolkit/components/places/tests/unit/test_bookmarks_html_escape_entities.js @@ -25,9 +25,11 @@ add_task(async function() { title: unescaped }); await PlacesUtils.keywords.insert({ url, keyword: unescaped, postData: unescaped }); - let uri = Services.io.newURI(url); - PlacesUtils.tagging.tagURI(uri, [unescaped]); - await PlacesUtils.setCharsetForURI(uri, unescaped); + PlacesUtils.tagging.tagURI(Services.io.newURI(url), [unescaped]); + await PlacesUtils.history.update({ + url, + annotations: new Map([[PlacesUtils.CHARSET_ANNO, unescaped]]), + }); PlacesUtils.annotations.setItemAnnotation( await PlacesUtils.promiseItemId(bm.guid), DESCRIPTION_ANNO, unescaped, 0, PlacesUtils.annotations.EXPIRE_NEVER); diff --git a/toolkit/components/places/tests/unit/test_promiseBookmarksTree.js b/toolkit/components/places/tests/unit/test_promiseBookmarksTree.js index ff0cf5e5962c..3e00065d68bd 100644 --- a/toolkit/components/places/tests/unit/test_promiseBookmarksTree.js +++ b/toolkit/components/places/tests/unit/test_promiseBookmarksTree.js @@ -212,7 +212,10 @@ add_task(async function() { annotations: [{ name: "TestAnnoA", value: "TestVal2"}]}); let urlWithCharsetAndFavicon = uri("http://charset.and.favicon"); await new_bookmark({ parentGuid: folderGuid, url: urlWithCharsetAndFavicon }); - await PlacesUtils.setCharsetForURI(urlWithCharsetAndFavicon, "UTF-8"); + await PlacesUtils.history.update({ + url: urlWithCharsetAndFavicon, + annotations: new Map([[PlacesUtils.CHARSET_ANNO, "UTF-16"]]), + }); await setFaviconForPage(urlWithCharsetAndFavicon, SMALLPNG_DATA_URI); // Test the default places root without specifying it. await test_promiseBookmarksTreeAgainstResult(); diff --git a/toolkit/components/places/tests/unit/xpcshell.ini b/toolkit/components/places/tests/unit/xpcshell.ini index 9f472d224314..c58e0ad0cf16 100644 --- a/toolkit/components/places/tests/unit/xpcshell.ini +++ b/toolkit/components/places/tests/unit/xpcshell.ini @@ -16,7 +16,6 @@ support-files = places.sparse.sqlite [test_000_frecency.js] -[test_317472.js] [test_331487.js] [test_384370.js] [test_385397.js] From e72c3371d99da919fc56a90dc300c506d50c72c8 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Wed, 1 Aug 2018 09:47:24 +0000 Subject: [PATCH 13/52] Bug 1479722 - Remove nsIAnnotationService::setPageAnnotation and removePageAnnotation. r=mak Depends on D2582 Differential Revision: https://phabricator.services.mozilla.com/D2583 --HG-- extra : moz-landing-system : lando --- .../sync/tests/unit/test_bookmark_tracker.js | 24 +- .../components/places/nsAnnotationService.cpp | 257 ++++-------------- .../components/places/nsAnnotationService.h | 18 +- .../places/nsIAnnotationService.idl | 19 -- .../expiration/test_annos_expire_never.js | 12 +- .../tests/expiration/test_clearHistory.js | 10 +- .../places/tests/history/test_fetch.js | 22 +- .../places/tests/history/test_remove.js | 6 +- .../history/test_removeVisitsByFilter.js | 6 +- .../test_preventive_maintenance.js | 5 +- .../places/tests/queries/head_queries.js | 21 +- .../places/tests/queries/test_415716.js | 10 +- .../test_downloadHistory_liveUpdate.js | 10 +- .../test_keyword_search_actions.js | 6 +- .../places/tests/unit/test_415757.js | 16 +- .../places/tests/unit/test_annotations.js | 29 +- .../places/tests/unit/test_browserhistory.js | 14 +- .../places/tests/unit/test_history.js | 8 +- .../places/tests/unit/test_history_clear.js | 7 +- .../places/tests/unit/test_telemetry.js | 6 +- 20 files changed, 165 insertions(+), 341 deletions(-) diff --git a/services/sync/tests/unit/test_bookmark_tracker.js b/services/sync/tests/unit/test_bookmark_tracker.js index da965dac8d36..014255997e09 100644 --- a/services/sync/tests/unit/test_bookmark_tracker.js +++ b/services/sync/tests/unit/test_bookmark_tracker.js @@ -787,25 +787,29 @@ add_task(async function test_onPageAnnoChanged() { await tracker.stop(); _("Insert a bookmark without an annotation"); - let pageURI = CommonUtils.makeURI("http://getfirefox.com"); - PlacesUtils.bookmarks.insertBookmark( - PlacesUtils.bookmarks.bookmarksMenuFolder, - pageURI, - PlacesUtils.bookmarks.DEFAULT_INDEX, - "Get Firefox!"); + let pageURI = "http://getfirefox.com"; + await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.menuGuid, + url: pageURI, + title: "Get Firefox!", + }); await startTracking(); _("Add a page annotation"); - PlacesUtils.annotations.setPageAnnotation(pageURI, "URIProperties/characterSet", - "UTF-8", 0, PlacesUtils.annotations.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: pageURI, + annotations: new Map([[PlacesUtils.CHARSET_ANNO, "UTF-16"]]), + }); await verifyTrackedItems([]); Assert.equal(tracker.score, 0); await resetTracker(); _("Remove the page annotation"); - PlacesUtils.annotations.removePageAnnotation(pageURI, - "URIProperties/characterSet"); + await PlacesUtils.history.update({ + url: pageURI, + annotations: new Map([[PlacesUtils.CHARSET_ANNO, null]]), + }); await verifyTrackedItems([]); Assert.equal(tracker.score, 0); } finally { diff --git a/toolkit/components/places/nsAnnotationService.cpp b/toolkit/components/places/nsAnnotationService.cpp index 180866fc6b72..4337d3b47ca4 100644 --- a/toolkit/components/places/nsAnnotationService.cpp +++ b/toolkit/components/places/nsAnnotationService.cpp @@ -165,8 +165,7 @@ nsAnnotationService::Init() } nsresult -nsAnnotationService::SetAnnotationStringInternal(nsIURI* aURI, - int64_t aItemId, +nsAnnotationService::SetAnnotationStringInternal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, const nsAString& aValue, @@ -176,7 +175,7 @@ nsAnnotationService::SetAnnotationStringInternal(nsIURI* aURI, mozStorageTransaction transaction(mDB->MainConn(), false); nsCOMPtr statement; - nsresult rv = StartSetAnnotation(aURI, aItemId, aBookmark, aName, aFlags, + nsresult rv = StartSetAnnotation(aItemId, aBookmark, aName, aFlags, aExpiration, nsIAnnotationService::TYPE_STRING, statement); @@ -197,87 +196,6 @@ nsAnnotationService::SetAnnotationStringInternal(nsIURI* aURI, } -NS_IMETHODIMP -nsAnnotationService::SetPageAnnotation(nsIURI* aURI, - const nsACString& aName, - nsIVariant* aValue, - int32_t aFlags, - uint16_t aExpiration) -{ - NS_ENSURE_ARG(aURI); - NS_ENSURE_ARG(aValue); - - uint16_t dataType; - nsresult rv = aValue->GetDataType(&dataType); - NS_ENSURE_SUCCESS(rv, rv); - - switch (dataType) { - case nsIDataType::VTYPE_INT8: - case nsIDataType::VTYPE_UINT8: - case nsIDataType::VTYPE_INT16: - case nsIDataType::VTYPE_UINT16: - case nsIDataType::VTYPE_INT32: - case nsIDataType::VTYPE_UINT32: - case nsIDataType::VTYPE_BOOL: { - int32_t valueInt; - rv = aValue->GetAsInt32(&valueInt); - if (NS_SUCCEEDED(rv)) { - NS_ENSURE_SUCCESS(rv, rv); - rv = SetAnnotationInt32Internal(aURI, 0, nullptr, aName, valueInt, - aFlags, aExpiration); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; - } - // Fall through int64_t case otherwise. - MOZ_FALLTHROUGH; - } - case nsIDataType::VTYPE_INT64: - case nsIDataType::VTYPE_UINT64: { - int64_t valueLong; - rv = aValue->GetAsInt64(&valueLong); - if (NS_SUCCEEDED(rv)) { - NS_ENSURE_SUCCESS(rv, rv); - rv = SetAnnotationInt64Internal(aURI, 0, nullptr, aName, valueLong, - aFlags, aExpiration); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; - } - // Fall through double case otherwise. - MOZ_FALLTHROUGH; - } - case nsIDataType::VTYPE_FLOAT: - case nsIDataType::VTYPE_DOUBLE: { - double valueDouble; - rv = aValue->GetAsDouble(&valueDouble); - NS_ENSURE_SUCCESS(rv, rv); - rv = SetAnnotationDoubleInternal(aURI, 0, nullptr, aName, valueDouble, - aFlags, aExpiration); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; - } - case nsIDataType::VTYPE_CHAR: - case nsIDataType::VTYPE_WCHAR: - case nsIDataType::VTYPE_DOMSTRING: - case nsIDataType::VTYPE_CHAR_STR: - case nsIDataType::VTYPE_WCHAR_STR: - case nsIDataType::VTYPE_STRING_SIZE_IS: - case nsIDataType::VTYPE_WSTRING_SIZE_IS: - case nsIDataType::VTYPE_UTF8STRING: - case nsIDataType::VTYPE_CSTRING: - case nsIDataType::VTYPE_ASTRING: { - nsAutoString stringValue; - rv = aValue->GetAsAString(stringValue); - NS_ENSURE_SUCCESS(rv, rv); - rv = SetAnnotationStringInternal(aURI, 0, nullptr, aName, stringValue, aFlags, aExpiration); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; - } - } - - return NS_ERROR_NOT_IMPLEMENTED; -} - - NS_IMETHODIMP nsAnnotationService::SetItemAnnotation(int64_t aItemId, const nsACString& aName, @@ -309,7 +227,7 @@ nsAnnotationService::SetItemAnnotation(int64_t aItemId, rv = aValue->GetAsInt32(&valueInt); if (NS_SUCCEEDED(rv)) { NS_ENSURE_SUCCESS(rv, rv); - rv = SetAnnotationInt32Internal(nullptr, aItemId, &bookmark, aName, + rv = SetAnnotationInt32Internal(aItemId, &bookmark, aName, valueInt, aFlags, aExpiration); NS_ENSURE_SUCCESS(rv, rv); break; @@ -323,7 +241,7 @@ nsAnnotationService::SetItemAnnotation(int64_t aItemId, rv = aValue->GetAsInt64(&valueLong); if (NS_SUCCEEDED(rv)) { NS_ENSURE_SUCCESS(rv, rv); - rv = SetAnnotationInt64Internal(nullptr, aItemId, &bookmark, aName, + rv = SetAnnotationInt64Internal(aItemId, &bookmark, aName, valueLong, aFlags, aExpiration); NS_ENSURE_SUCCESS(rv, rv); break; @@ -336,7 +254,7 @@ nsAnnotationService::SetItemAnnotation(int64_t aItemId, double valueDouble; rv = aValue->GetAsDouble(&valueDouble); NS_ENSURE_SUCCESS(rv, rv); - rv = SetAnnotationDoubleInternal(nullptr, aItemId, &bookmark, + rv = SetAnnotationDoubleInternal(aItemId, &bookmark, aName, valueDouble, aFlags, aExpiration); NS_ENSURE_SUCCESS(rv, rv); break; @@ -354,7 +272,7 @@ nsAnnotationService::SetItemAnnotation(int64_t aItemId, nsAutoString stringValue; rv = aValue->GetAsAString(stringValue); NS_ENSURE_SUCCESS(rv, rv); - rv = SetAnnotationStringInternal(nullptr, aItemId, &bookmark, aName, + rv = SetAnnotationStringInternal(aItemId, &bookmark, aName, stringValue, aFlags, aExpiration); NS_ENSURE_SUCCESS(rv, rv); break; @@ -370,8 +288,7 @@ nsAnnotationService::SetItemAnnotation(int64_t aItemId, nsresult -nsAnnotationService::SetAnnotationInt32Internal(nsIURI* aURI, - int64_t aItemId, +nsAnnotationService::SetAnnotationInt32Internal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, int32_t aValue, @@ -380,7 +297,7 @@ nsAnnotationService::SetAnnotationInt32Internal(nsIURI* aURI, { mozStorageTransaction transaction(mDB->MainConn(), false); nsCOMPtr statement; - nsresult rv = StartSetAnnotation(aURI, aItemId, aBookmark, aName, aFlags, + nsresult rv = StartSetAnnotation(aItemId, aBookmark, aName, aFlags, aExpiration, nsIAnnotationService::TYPE_INT32, statement); @@ -402,8 +319,7 @@ nsAnnotationService::SetAnnotationInt32Internal(nsIURI* aURI, nsresult -nsAnnotationService::SetAnnotationInt64Internal(nsIURI* aURI, - int64_t aItemId, +nsAnnotationService::SetAnnotationInt64Internal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, int64_t aValue, @@ -412,7 +328,7 @@ nsAnnotationService::SetAnnotationInt64Internal(nsIURI* aURI, { mozStorageTransaction transaction(mDB->MainConn(), false); nsCOMPtr statement; - nsresult rv = StartSetAnnotation(aURI, aItemId, aBookmark, aName, aFlags, + nsresult rv = StartSetAnnotation(aItemId, aBookmark, aName, aFlags, aExpiration, nsIAnnotationService::TYPE_INT64, statement); @@ -434,8 +350,7 @@ nsAnnotationService::SetAnnotationInt64Internal(nsIURI* aURI, nsresult -nsAnnotationService::SetAnnotationDoubleInternal(nsIURI* aURI, - int64_t aItemId, +nsAnnotationService::SetAnnotationDoubleInternal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, double aValue, @@ -444,7 +359,7 @@ nsAnnotationService::SetAnnotationDoubleInternal(nsIURI* aURI, { mozStorageTransaction transaction(mDB->MainConn(), false); nsCOMPtr statement; - nsresult rv = StartSetAnnotation(aURI, aItemId, aBookmark, aName, aFlags, + nsresult rv = StartSetAnnotation(aItemId, aBookmark, aName, aFlags, aExpiration, nsIAnnotationService::TYPE_DOUBLE, statement); @@ -778,38 +693,22 @@ nsAnnotationService::GetItemAnnotationNames(int64_t aItemId, * It will be cleaned up by expiration. */ nsresult -nsAnnotationService::RemoveAnnotationInternal(nsIURI* aURI, - int64_t aItemId, +nsAnnotationService::RemoveAnnotationInternal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName) { - bool isItemAnnotation = (aItemId > 0); nsCOMPtr statement; - if (isItemAnnotation) { - statement = mDB->GetStatement( - "DELETE FROM moz_items_annos " - "WHERE item_id = :item_id " - "AND anno_attribute_id = " - "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name)" - ); - } - else { - statement = mDB->GetStatement( - "DELETE FROM moz_annos " - "WHERE place_id = " - "(SELECT id FROM moz_places WHERE url_hash = hash(:page_url) AND url = :page_url) " - "AND anno_attribute_id = " - "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name)" - ); - } + statement = mDB->GetStatement( + "DELETE FROM moz_items_annos " + "WHERE item_id = :item_id " + "AND anno_attribute_id = " + "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name)" + ); NS_ENSURE_STATE(statement); mozStorageStatementScoper scoper(statement); nsresult rv; - if (isItemAnnotation) - rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId); - else - rv = URIBinder::Bind(statement, NS_LITERAL_CSTRING("page_url"), aURI); + rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId); NS_ENSURE_SUCCESS(rv, rv); rv = statement->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName); @@ -818,13 +717,11 @@ nsAnnotationService::RemoveAnnotationInternal(nsIURI* aURI, rv = statement->Execute(); NS_ENSURE_SUCCESS(rv, rv); - if (isItemAnnotation) { - nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService(); - if (bookmarks) { - MOZ_ASSERT(aBookmark); - if (NS_FAILED(bookmarks->FetchItemInfo(aItemId, *aBookmark))) { - aBookmark->id = -1; - } + nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService(); + if (bookmarks) { + MOZ_ASSERT(aBookmark); + if (NS_FAILED(bookmarks->FetchItemInfo(aItemId, *aBookmark))) { + aBookmark->id = -1; } } @@ -832,19 +729,6 @@ nsAnnotationService::RemoveAnnotationInternal(nsIURI* aURI, } -NS_IMETHODIMP -nsAnnotationService::RemovePageAnnotation(nsIURI* aURI, - const nsACString& aName) -{ - NS_ENSURE_ARG(aURI); - - nsresult rv = RemoveAnnotationInternal(aURI, 0, nullptr, aName); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - - NS_IMETHODIMP nsAnnotationService::RemoveItemAnnotation(int64_t aItemId, const nsACString& aName, @@ -853,7 +737,7 @@ nsAnnotationService::RemoveItemAnnotation(int64_t aItemId, NS_ENSURE_ARG_MIN(aItemId, 1); BookmarkData bookmark; - nsresult rv = RemoveAnnotationInternal(nullptr, aItemId, &bookmark, aName); + nsresult rv = RemoveAnnotationInternal(aItemId, &bookmark, aName); NS_ENSURE_SUCCESS(rv, rv); NotifyItemChanged(bookmark, aName, aSource, false); @@ -1002,8 +886,7 @@ nsAnnotationService::StartGetAnnotation(nsIURI* aURI, * The caller must take care of resetting the statement if this succeeds. */ nsresult -nsAnnotationService::StartSetAnnotation(nsIURI* aURI, - int64_t aItemId, +nsAnnotationService::StartSetAnnotation(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, int32_t aFlags, @@ -1014,8 +897,6 @@ nsAnnotationService::StartSetAnnotation(nsIURI* aURI, MOZ_ASSERT(aExpiration == EXPIRE_NEVER, "Only EXPIRE_NEVER is supported"); NS_ENSURE_ARG(aExpiration == EXPIRE_NEVER); - bool isItemAnnotation = (aItemId > 0); - // Ensure the annotation name exists. nsCOMPtr addNameStmt = mDB->GetStatement( "INSERT OR IGNORE INTO moz_anno_attributes (name) VALUES (:anno_name)" @@ -1036,39 +917,22 @@ nsAnnotationService::StartSetAnnotation(nsIURI* aURI, // - whether the annotation already exists. // - the nameID associated with the annotation name. // - the id and dateAdded of the old annotation, if it exists. - nsCOMPtr stmt; - if (isItemAnnotation) { - stmt = mDB->GetStatement( - "SELECT b.id, " - "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name) AS nameid, " - "a.id, a.dateAdded, b.parent, b.type, b.lastModified, b.guid, p.guid " - "FROM moz_bookmarks b " - "JOIN moz_bookmarks p ON p.id = b.parent " - "LEFT JOIN moz_items_annos a ON a.item_id = b.id " - "AND a.anno_attribute_id = nameid " - "WHERE b.id = :item_id" - ); - } - else { - stmt = mDB->GetStatement( - "SELECT h.id, " - "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name) AS nameid, " - "a.id, a.dateAdded " - "FROM moz_places h " - "LEFT JOIN moz_annos a ON a.place_id = h.id " - "AND a.anno_attribute_id = nameid " - "WHERE h.url_hash = hash(:page_url) AND h.url = :page_url" - ); - } + nsCOMPtr stmt = mDB->GetStatement( + "SELECT b.id, " + "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name) AS nameid, " + "a.id, a.dateAdded, b.parent, b.type, b.lastModified, b.guid, p.guid " + "FROM moz_bookmarks b " + "JOIN moz_bookmarks p ON p.id = b.parent " + "LEFT JOIN moz_items_annos a ON a.item_id = b.id " + "AND a.anno_attribute_id = nameid " + "WHERE b.id = :item_id" + ); NS_ENSURE_STATE(stmt); mozStorageStatementScoper checkAnnoScoper(stmt); rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName); NS_ENSURE_SUCCESS(rv, rv); - if (isItemAnnotation) - rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId); - else - rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("page_url"), aURI); + rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId); NS_ENSURE_SUCCESS(rv, rv); bool hasResult; @@ -1085,36 +949,25 @@ nsAnnotationService::StartSetAnnotation(nsIURI* aURI, int64_t oldAnnoId = stmt->AsInt64(2); int64_t oldAnnoDate = stmt->AsInt64(3); - if (isItemAnnotation) { - aStatement = mDB->GetStatement( - "INSERT OR REPLACE INTO moz_items_annos " - "(id, item_id, anno_attribute_id, content, flags, " - "expiration, type, dateAdded, lastModified) " - "VALUES (:id, :fk, :name_id, :content, :flags, " - ":expiration, :type, :date_added, :last_modified)" - ); + aStatement = mDB->GetStatement( + "INSERT OR REPLACE INTO moz_items_annos " + "(id, item_id, anno_attribute_id, content, flags, " + "expiration, type, dateAdded, lastModified) " + "VALUES (:id, :fk, :name_id, :content, :flags, " + ":expiration, :type, :date_added, :last_modified)" + ); - // Since we're already querying `moz_bookmarks`, we fetch the changed - // bookmark's info here, instead of using `FetchItemInfo`. - MOZ_ASSERT(aBookmark); - aBookmark->id = fkId; - aBookmark->parentId = stmt->AsInt64(4); - aBookmark->type = stmt->AsInt64(5); + // Since we're already querying `moz_bookmarks`, we fetch the changed + // bookmark's info here, instead of using `FetchItemInfo`. + MOZ_ASSERT(aBookmark); + aBookmark->id = fkId; + aBookmark->parentId = stmt->AsInt64(4); + aBookmark->type = stmt->AsInt64(5); - aBookmark->lastModified = static_cast(stmt->AsInt64(6)); - if (NS_FAILED(stmt->GetUTF8String(7, aBookmark->guid)) || - NS_FAILED(stmt->GetUTF8String(8, aBookmark->parentGuid))) { - aBookmark->id = -1; - } - } - else { - aStatement = mDB->GetStatement( - "INSERT OR REPLACE INTO moz_annos " - "(id, place_id, anno_attribute_id, content, flags, " - "expiration, type, dateAdded, lastModified) " - "VALUES (:id, :fk, :name_id, :content, :flags, " - ":expiration, :type, :date_added, :last_modified)" - ); + aBookmark->lastModified = static_cast(stmt->AsInt64(6)); + if (NS_FAILED(stmt->GetUTF8String(7, aBookmark->guid)) || + NS_FAILED(stmt->GetUTF8String(8, aBookmark->parentGuid))) { + aBookmark->id = -1; } NS_ENSURE_STATE(aStatement); mozStorageStatementScoper setAnnoScoper(aStatement); diff --git a/toolkit/components/places/nsAnnotationService.h b/toolkit/components/places/nsAnnotationService.h index 3d29d728e6eb..76821ffb53ba 100644 --- a/toolkit/components/places/nsAnnotationService.h +++ b/toolkit/components/places/nsAnnotationService.h @@ -102,8 +102,7 @@ protected: const nsACString& aName, nsCOMPtr& aStatement); - nsresult StartSetAnnotation(nsIURI* aURI, - int64_t aItemId, + nsresult StartSetAnnotation(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, int32_t aFlags, @@ -111,37 +110,32 @@ protected: uint16_t aType, nsCOMPtr& aStatement); - nsresult SetAnnotationStringInternal(nsIURI* aURI, - int64_t aItemId, + nsresult SetAnnotationStringInternal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, const nsAString& aValue, int32_t aFlags, uint16_t aExpiration); - nsresult SetAnnotationInt32Internal(nsIURI* aURI, - int64_t aItemId, + nsresult SetAnnotationInt32Internal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, int32_t aValue, int32_t aFlags, uint16_t aExpiration); - nsresult SetAnnotationInt64Internal(nsIURI* aURI, - int64_t aItemId, + nsresult SetAnnotationInt64Internal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, int64_t aValue, int32_t aFlags, uint16_t aExpiration); - nsresult SetAnnotationDoubleInternal(nsIURI* aURI, - int64_t aItemId, + nsresult SetAnnotationDoubleInternal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName, double aValue, int32_t aFlags, uint16_t aExpiration); - nsresult RemoveAnnotationInternal(nsIURI* aURI, - int64_t aItemId, + nsresult RemoveAnnotationInternal(int64_t aItemId, BookmarkData* aBookmark, const nsACString& aName); diff --git a/toolkit/components/places/nsIAnnotationService.idl b/toolkit/components/places/nsIAnnotationService.idl index 18562a171100..09a923890388 100644 --- a/toolkit/components/places/nsIAnnotationService.idl +++ b/toolkit/components/places/nsIAnnotationService.idl @@ -54,18 +54,6 @@ interface nsIAnnotationService : nsISupports * aExpiration is one of EXPIRE_* above. aFlags should be 0 for now, some * flags will be defined in the future. * - * NOTE: ALL PAGE ANNOTATIONS WILL GET DELETED WHEN THE PAGE IS REMOVED FROM - * HISTORY IF THE PAGE IS NOT BOOKMARKED. This means that if you create an - * annotation on an unvisited URI, it will get deleted when the browser - * shuts down. Otherwise, URIs can exist in history as annotations but the - * user has no way of knowing it, potentially violating their privacy - * expectations about actions such as "Clear history". - * If there is an important annotation that the user or extension wants to - * keep, you should add a bookmark for the page and use an EXPIRE_NEVER - * annotation. This will ensure the annotation exists until the item is - * removed by the user. - * See EXPIRE_* constants above for further information. - * * For item annotations, aSource should be a change source constant from * nsINavBookmarksService::SOURCE_*, and defaults to SOURCE_DEFAULT if * omitted. Setting an item annotation also notifies @@ -79,11 +67,6 @@ interface nsIAnnotationService : nsISupports * * @throws NS_ERROR_ILLEGAL_VALUE if the page or the bookmark doesn't exist. */ - void setPageAnnotation(in nsIURI aURI, - in AUTF8String aName, - in nsIVariant aValue, - in long aFlags, - in unsigned short aExpiration); void setItemAnnotation(in long long aItemId, in AUTF8String aName, in nsIVariant aValue, @@ -158,8 +141,6 @@ interface nsIAnnotationService : nsISupports * Removing an item annotation also notifies * `nsINavBookmarkObserver::onItemChanged` for the affected item. */ - void removePageAnnotation(in nsIURI aURI, - in AUTF8String aName); void removeItemAnnotation(in long long aItemId, in AUTF8String aName, [optional] in unsigned short aSource); diff --git a/toolkit/components/places/tests/expiration/test_annos_expire_never.js b/toolkit/components/places/tests/expiration/test_annos_expire_never.js index 7bc8c345a34b..872b7e5ea891 100644 --- a/toolkit/components/places/tests/expiration/test_annos_expire_never.js +++ b/toolkit/components/places/tests/expiration/test_annos_expire_never.js @@ -30,8 +30,10 @@ add_task(async function test_annos_expire_never() { for (let i = 0; i < 5; i++) { let pageURI = uri("http://page_anno." + i + ".mozilla.org/"); await PlacesTestUtils.addVisits({ uri: pageURI, visitDate: now++ }); - as.setPageAnnotation(pageURI, "page_expire1", "test", 0, as.EXPIRE_NEVER); - as.setPageAnnotation(pageURI, "page_expire2", "test", 0, as.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: pageURI, + annotations: new Map([["page_expire1", "test"], ["page_expire2", "test"]]), + }); } let pages = await getPagesWithAnnotation("page_expire1"); @@ -64,8 +66,10 @@ add_task(async function test_annos_expire_never() { for (let i = 0; i < 5; i++) { let pageURI = uri("http://persist_page_anno." + i + ".mozilla.org/"); await PlacesTestUtils.addVisits({ uri: pageURI, visitDate: now++ }); - as.setPageAnnotation(pageURI, "page_persist1", "test", 0, as.EXPIRE_NEVER); - as.setPageAnnotation(pageURI, "page_persist2", "test", 0, as.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: pageURI, + annotations: new Map([["page_persist1", "test"], ["page_persist2", "test"]]), + }); } pages = await getPagesWithAnnotation("page_persist1"); diff --git a/toolkit/components/places/tests/expiration/test_clearHistory.js b/toolkit/components/places/tests/expiration/test_clearHistory.js index 14196b6cbd76..8d9a24310121 100644 --- a/toolkit/components/places/tests/expiration/test_clearHistory.js +++ b/toolkit/components/places/tests/expiration/test_clearHistory.js @@ -33,7 +33,10 @@ add_task(async function test_historyClear() { // Will persist because it's an EXPIRE_NEVER item anno. as.setItemAnnotation(id, "persist", "test", 0, as.EXPIRE_NEVER); // Will persist because the page is bookmarked. - as.setPageAnnotation(pageURI, "persist", "test", 0, as.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: pageURI, + annotations: new Map([["persist", "test"]]), + }); } // Add some visited page and annotations for each. @@ -42,7 +45,10 @@ add_task(async function test_historyClear() { // expire as well. let pageURI = uri("http://page_anno." + i + ".mozilla.org/"); await PlacesTestUtils.addVisits({ uri: pageURI }); - as.setPageAnnotation(pageURI, "expire", "test", 0, as.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: pageURI, + annotations: new Map([["expire", "test"]]), + }); } // Expire all visits for the bookmarks diff --git a/toolkit/components/places/tests/history/test_fetch.js b/toolkit/components/places/tests/history/test_fetch.js index 2740d6cdacfd..6bb0d6e4fe07 100644 --- a/toolkit/components/places/tests/history/test_fetch.js +++ b/toolkit/components/places/tests/history/test_fetch.js @@ -118,13 +118,10 @@ add_task(async function test_fetch_annotations() { Assert.equal(pageInfo.annotations.size, 0, "fetch should return an empty annotation map"); - PlacesUtils.annotations.setPageAnnotation( - Services.io.newURI(TEST_URI), - "test/annotation", - "testContent", - 0, - PlacesUtils.annotations.EXPIRE_NEVER - ); + await PlacesUtils.history.update({ + url: TEST_URI, + annotations: new Map([["test/annotation", "testContent"]]), + }); pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations}); Assert.equal(pageInfo.annotations.size, 1, @@ -133,13 +130,10 @@ add_task(async function test_fetch_annotations() { Assert.equal(pageInfo.annotations.get("test/annotation"), "testContent", "fetch should return the expected annotation"); - PlacesUtils.annotations.setPageAnnotation( - Services.io.newURI(TEST_URI), - "test/annotation2", - 123, - 0, - PlacesUtils.annotations.EXPIRE_NEVER - ); + await PlacesUtils.history.update({ + url: TEST_URI, + annotations: new Map([["test/annotation2", 123]]), + }); pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations}); Assert.equal(pageInfo.annotations.size, 2, diff --git a/toolkit/components/places/tests/history/test_remove.js b/toolkit/components/places/tests/history/test_remove.js index ea76ab31de7a..9bd954857ed1 100644 --- a/toolkit/components/places/tests/history/test_remove.js +++ b/toolkit/components/places/tests/history/test_remove.js @@ -218,8 +218,10 @@ add_task(async function test_orphans() { uri, faviconURI, true, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, null, Services.scriptSecurityManager.getSystemPrincipal()); - PlacesUtils.annotations.setPageAnnotation(uri, "test", "restval", 0, - PlacesUtils.annotations.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: uri, + annotations: new Map([["test", "restval"]]), + }); await PlacesUtils.history.remove(uri); Assert.ok(!(await PlacesTestUtils.isPageInDB(uri)), "Page should have been removed"); diff --git a/toolkit/components/places/tests/history/test_removeVisitsByFilter.js b/toolkit/components/places/tests/history/test_removeVisitsByFilter.js index 67540c77896d..6d4db77f261f 100644 --- a/toolkit/components/places/tests/history/test_removeVisitsByFilter.js +++ b/toolkit/components/places/tests/history/test_removeVisitsByFilter.js @@ -333,8 +333,10 @@ add_task(async function test_orphans() { PlacesUtils.favicons.setAndFetchFaviconForPage( uri, SMALLPNG_DATA_URI, true, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, null, Services.scriptSecurityManager.getSystemPrincipal()); - PlacesUtils.annotations.setPageAnnotation(uri, "test", "restval", 0, - PlacesUtils.annotations.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: uri, + annotations: new Map([["test", "restval"]]), + }); await PlacesUtils.history.removeVisitsByFilter({ beginDate: new Date(1999, 9, 9, 9, 9), endDate: new Date() }); diff --git a/toolkit/components/places/tests/maintenance/test_preventive_maintenance.js b/toolkit/components/places/tests/maintenance/test_preventive_maintenance.js index 4ab865c69ae5..b34999fee142 100644 --- a/toolkit/components/places/tests/maintenance/test_preventive_maintenance.js +++ b/toolkit/components/places/tests/maintenance/test_preventive_maintenance.js @@ -2153,7 +2153,10 @@ tests.push({ null, Services.scriptSecurityManager.getSystemPrincipal()); await PlacesUtils.keywords.insert({ url: this._uri1.spec, keyword: "testkeyword" }); - as.setPageAnnotation(this._uri2, "anno", "anno", 0, as.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: this._uri2, + annotations: new Map([["anno", "anno"]]), + }); as.setItemAnnotation(this._bookmarkId, "anno", "anno", 0, as.EXPIRE_NEVER); }, diff --git a/toolkit/components/places/tests/queries/head_queries.js b/toolkit/components/places/tests/queries/head_queries.js index 8c7a9c148c98..cf4f2fb243e5 100644 --- a/toolkit/components/places/tests/queries/head_queries.js +++ b/toolkit/components/places/tests/queries/head_queries.js @@ -96,16 +96,13 @@ async function task_populateDB(aArray) { } if (qdata.isPageAnnotation) { - if (qdata.removeAnnotation) - PlacesUtils.annotations.removePageAnnotation(uri(qdata.uri), - qdata.annoName); - else { - PlacesUtils.annotations.setPageAnnotation(uri(qdata.uri), - qdata.annoName, - qdata.annoVal, - qdata.annoFlags, - PlacesUtils.annotations.EXPIRE_NEVER); - } + await PlacesUtils.history.update({ + url: qdata.uri, + annotations: new Map([[ + qdata.annoName, + qdata.removeAnnotation ? null : qdata.annoVal + ]]), + }); } if (qdata.isItemAnnotation) { @@ -116,7 +113,7 @@ async function task_populateDB(aArray) { PlacesUtils.annotations.setItemAnnotation(qdata.itemId, qdata.annoName, qdata.annoVal, - qdata.annoFlags, + 0, PlacesUtils.annotations.EXPIRE_NEVER); } } @@ -209,8 +206,6 @@ function queryData(obj) { this.removeAnnotation = !!obj.removeAnnotation; this.annoName = obj.annoName ? obj.annoName : ""; this.annoVal = obj.annoVal ? obj.annoVal : ""; - this.annoFlags = obj.annoFlags ? obj.annoFlags : 0; - this.annoExpiration = obj.annoExpiration ? obj.annoExpiration : 0; this.isItemAnnotation = obj.isItemAnnotation ? obj.isItemAnnotation : false; this.itemId = obj.itemId ? obj.itemId : 0; this.annoMimeType = obj.annoMimeType ? obj.annoMimeType : ""; diff --git a/toolkit/components/places/tests/queries/test_415716.js b/toolkit/components/places/tests/queries/test_415716.js index 1320bb9b92b0..ad1db1be47a0 100644 --- a/toolkit/components/places/tests/queries/test_415716.js +++ b/toolkit/components/places/tests/queries/test_415716.js @@ -34,7 +34,7 @@ function modHistoryTypes(val) { add_task(async function test_buildTestDatabase() { // This is the set of visits that we will match - our min visit is 2 so that's // why we add more visits to the same URIs. - let testURI = uri("http://www.foo.com"); + let testURI = "http://www.foo.com"; let places = []; for (let i = 0; i < 12; ++i) { @@ -45,7 +45,7 @@ add_task(async function test_buildTestDatabase() { }); } - testURI = uri("http://foo.com/youdontseeme.html"); + testURI = "http://foo.com/youdontseeme.html"; let testAnnoName = "moz-test-places/testing123"; let testAnnoVal = "test"; for (let i = 0; i < 12; ++i) { @@ -58,8 +58,10 @@ add_task(async function test_buildTestDatabase() { await PlacesTestUtils.addVisits(places); - PlacesUtils.annotations.setPageAnnotation(testURI, testAnnoName, - testAnnoVal, 0, PlacesUtils.annotations.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: testURI, + annotations: new Map([[testAnnoName, testAnnoVal]]), + }); }); /** diff --git a/toolkit/components/places/tests/queries/test_downloadHistory_liveUpdate.js b/toolkit/components/places/tests/queries/test_downloadHistory_liveUpdate.js index faa5fb7b2b6f..d0c105d1729d 100644 --- a/toolkit/components/places/tests/queries/test_downloadHistory_liveUpdate.js +++ b/toolkit/components/places/tests/queries/test_downloadHistory_liveUpdate.js @@ -39,7 +39,7 @@ add_task(async function test_downloadhistory_query_notifications() { // Add more maxResults downloads in order. let transitions = Object.values(PlacesUtils.history.TRANSITIONS); for (let transition of transitions) { - let uri = Services.io.newURI("http://fx-search.com/" + transition); + let uri = "http://fx-search.com/" + transition; await PlacesTestUtils.addVisits({ uri, transition, title: "test " + transition }); // For each visit also set apart: // - a bookmark @@ -49,9 +49,11 @@ add_task(async function test_downloadhistory_query_notifications() { url: uri, parentGuid: PlacesUtils.bookmarks.unfiledGuid }); - PlacesUtils.annotations.setPageAnnotation(uri, "test/anno", "testValue", 0, - PlacesUtils.annotations.EXPIRE_NEVER); - await PlacesTestUtils.addFavicons(new Map([[uri.spec, SMALLPNG_DATA_URI.spec]])); + await PlacesUtils.history.update({ + url: uri, + annotations: new Map([["test/anno", "testValue"]]), + }); + await PlacesTestUtils.addFavicons(new Map([[uri, SMALLPNG_DATA_URI.spec]])); } // Remove all the visits one by one. for (let transition of transitions) { diff --git a/toolkit/components/places/tests/unifiedcomplete/test_keyword_search_actions.js b/toolkit/components/places/tests/unifiedcomplete/test_keyword_search_actions.js index ca98c586a901..c70478dc5619 100644 --- a/toolkit/components/places/tests/unifiedcomplete/test_keyword_search_actions.js +++ b/toolkit/components/places/tests/unifiedcomplete/test_keyword_search_actions.js @@ -32,8 +32,10 @@ add_task(async function test_keyword_search() { await addBookmark({ uri: uri5, title: "Keyword", keyword: "key2"}); await addBookmark({ uri: uri6, title: "Charset-history", keyword: "charset_history"}); - PlacesUtils.annotations.setPageAnnotation(Services.io.newURI(uri6), - PlacesUtils.CHARSET_ANNO, "ISO-8859-1", 0, PlacesUtils.annotations.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: uri6, + annotations: new Map([[PlacesUtils.CHARSET_ANNO, "ISO-8859-1"]]), + }); info("Plain keyword query"); await check_autocomplete({ diff --git a/toolkit/components/places/tests/unit/test_415757.js b/toolkit/components/places/tests/unit/test_415757.js index 4b563ffdd3a9..9d5d0f70f338 100644 --- a/toolkit/components/places/tests/unit/test_415757.js +++ b/toolkit/components/places/tests/unit/test_415757.js @@ -47,19 +47,19 @@ add_task(async function test_execute() { var testAnnoDeletedURI = uri("http://www.test.com/1/"); var testAnnoDeletedName = "foo"; var testAnnoDeletedValue = "bar"; - PlacesUtils.annotations.setPageAnnotation(testAnnoDeletedURI, - testAnnoDeletedName, - testAnnoDeletedValue, 0, - PlacesUtils.annotations.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: testAnnoDeletedURI, + annotations: new Map([[testAnnoDeletedName, testAnnoDeletedValue]]), + }); // set a page annotation on one of the urls that will NOT be removed var testAnnoRetainedURI = uri("http://www.test-1.com/"); var testAnnoRetainedName = "foo"; var testAnnoRetainedValue = "bar"; - PlacesUtils.annotations.setPageAnnotation(testAnnoRetainedURI, - testAnnoRetainedName, - testAnnoRetainedValue, 0, - PlacesUtils.annotations.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: testAnnoRetainedURI, + annotations: new Map([[testAnnoRetainedName, testAnnoRetainedValue]]), + }); // remove pages from www.test.com await PlacesUtils.history.removeByFilter({ host: "www.test.com" }); diff --git a/toolkit/components/places/tests/unit/test_annotations.js b/toolkit/components/places/tests/unit/test_annotations.js index a12920de1819..d02fc77f3135 100644 --- a/toolkit/components/places/tests/unit/test_annotations.js +++ b/toolkit/components/places/tests/unit/test_annotations.js @@ -23,16 +23,6 @@ add_task(async function test_execute() { let testAnnoVal = "test"; let earlierDate = new Date(Date.now() - 1000); - // create new string annotation - try { - annosvc.setPageAnnotation(testURI, testAnnoName, testAnnoVal, 0, annosvc.EXPIRE_NEVER); - } catch (ex) { - do_throw("unable to add page-annotation"); - } - - // get string annotation - var storedAnnoVal = annosvc.getPageAnnotation(testURI, testAnnoName); - Assert.ok(testAnnoVal === storedAnnoVal); // string item-annotation let item = await PlacesUtils.bookmarks.fetch(testItem.guid); @@ -88,23 +78,16 @@ add_task(async function test_execute() { // test int32 anno type var int32Key = testAnnoName + "/types/Int32"; var int32Val = 23; - annosvc.setPageAnnotation(testURI, int32Key, int32Val, 0, annosvc.EXPIRE_NEVER); - value = {}, flags = {}, exp = {}, storageType = {}; - var storedVal = annosvc.getPageAnnotation(testURI, int32Key); - Assert.ok(int32Val === storedVal); annosvc.setItemAnnotation(testItemId, int32Key, int32Val, 0, annosvc.EXPIRE_NEVER); Assert.ok(annosvc.itemHasAnnotation(testItemId, int32Key)); annosvc.getItemAnnotationInfo(testItemId, int32Key, value, flags, exp, storageType); Assert.equal(value.value, int32Val); - storedVal = annosvc.getItemAnnotation(testItemId, int32Key); + let storedVal = annosvc.getItemAnnotation(testItemId, int32Key); Assert.ok(int32Val === storedVal); // test int64 anno type var int64Key = testAnnoName + "/types/Int64"; var int64Val = 4294967296; - annosvc.setPageAnnotation(testURI, int64Key, int64Val, 0, annosvc.EXPIRE_NEVER); - storedVal = annosvc.getPageAnnotation(testURI, int64Key); - Assert.ok(int64Val === storedVal); annosvc.setItemAnnotation(testItemId, int64Key, int64Val, 0, annosvc.EXPIRE_NEVER); Assert.ok(annosvc.itemHasAnnotation(testItemId, int64Key)); annosvc.getItemAnnotationInfo(testItemId, int64Key, value, flags, exp, storageType); @@ -115,9 +98,6 @@ add_task(async function test_execute() { // test double anno type var doubleKey = testAnnoName + "/types/Double"; var doubleVal = 0.000002342; - annosvc.setPageAnnotation(testURI, doubleKey, doubleVal, 0, annosvc.EXPIRE_NEVER); - storedVal = annosvc.getPageAnnotation(testURI, doubleKey); - Assert.ok(doubleVal === storedVal); annosvc.setItemAnnotation(testItemId, doubleKey, doubleVal, 0, annosvc.EXPIRE_NEVER); Assert.ok(annosvc.itemHasAnnotation(testItemId, doubleKey)); annosvc.getItemAnnotationInfo(testItemId, doubleKey, value, flags, exp, storageType); @@ -127,8 +107,6 @@ add_task(async function test_execute() { Assert.ok(doubleVal === storedVal); // test annotation removal - annosvc.removePageAnnotation(testURI, int32Key); - annosvc.setItemAnnotation(testItemId, testAnnoName, testAnnoVal, 0, annosvc.EXPIRE_NEVER); // verify that removing an annotation updates the last modified date testItem = await PlacesUtils.bookmarks.fetch(testItem.guid); @@ -193,9 +171,6 @@ add_task(async function test_getAnnotationsHavingName() { "string": "seven" }; for (let name in ANNOS) { - PlacesUtils.annotations.setPageAnnotation( - url, name, ANNOS[name], 0, - PlacesUtils.annotations.EXPIRE_NEVER); PlacesUtils.annotations.setItemAnnotation( id, name, ANNOS[name], 0, PlacesUtils.annotations.EXPIRE_NEVER); @@ -206,7 +181,7 @@ add_task(async function test_getAnnotationsHavingName() { for (let name in ANNOS) { let results = PlacesUtils.annotations.getAnnotationsWithName(name); - Assert.equal(results.length, 3); + Assert.equal(results.length, 2); for (let result of results) { Assert.equal(result.annotationName, name); diff --git a/toolkit/components/places/tests/unit/test_browserhistory.js b/toolkit/components/places/tests/unit/test_browserhistory.js index 3351f29b9aa3..81452ebff3c1 100644 --- a/toolkit/components/places/tests/unit/test_browserhistory.js +++ b/toolkit/components/places/tests/unit/test_browserhistory.js @@ -35,17 +35,19 @@ add_task(async function test_removePages() { const ANNO_NAME = "testAnno"; const ANNO_VALUE = "foo"; const BOOKMARK_INDEX = 2; - PlacesUtils.annotations.setPageAnnotation(pages[ANNO_INDEX], - ANNO_NAME, ANNO_VALUE, 0, - Ci.nsIAnnotationService.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: pages[ANNO_INDEX], + annotations: new Map([[ANNO_NAME, ANNO_VALUE]]), + }); await PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid, url: pages[BOOKMARK_INDEX], title: "test bookmark" }); - PlacesUtils.annotations.setPageAnnotation(pages[BOOKMARK_INDEX], - ANNO_NAME, ANNO_VALUE, 0, - Ci.nsIAnnotationService.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: pages[BOOKMARK_INDEX], + annotations: new Map([[ANNO_NAME, ANNO_VALUE]]), + }); await PlacesUtils.history.remove(pages); Assert.ok(await checkEmptyHistory(), "History is empty"); diff --git a/toolkit/components/places/tests/unit/test_history.js b/toolkit/components/places/tests/unit/test_history.js index 9bf13fae3ac9..3b8078ebc3aa 100644 --- a/toolkit/components/places/tests/unit/test_history.js +++ b/toolkit/components/places/tests/unit/test_history.js @@ -117,10 +117,10 @@ add_task(async function test_execute() { result.root.containerOpen = false; // test annotation-based queries - var annos = Cc["@mozilla.org/browser/annotation-service;1"]. - getService(Ci.nsIAnnotationService); - annos.setPageAnnotation(uri("http://mozilla.com/"), "testAnno", 0, 0, - Ci.nsIAnnotationService.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: "http://mozilla.com/", + annotations: new Map([["testAnno", 123]]), + }); query.annotation = "testAnno"; result = histsvc.executeQuery(query, options); result.root.containerOpen = true; diff --git a/toolkit/components/places/tests/unit/test_history_clear.js b/toolkit/components/places/tests/unit/test_history_clear.js index 5300ffd89848..2558bd57f686 100644 --- a/toolkit/components/places/tests/unit/test_history_clear.js +++ b/toolkit/components/places/tests/unit/test_history_clear.js @@ -32,9 +32,10 @@ add_task(async function test_history_clear() { // Add an expire never annotation // Actually expire never annotations are removed as soon as a page is removed // from the database, so this should act as a normal visit. - PlacesUtils.annotations.setPageAnnotation(uri("http://download.mozilla.org/"), - "never", "never", 0, - PlacesUtils.annotations.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: "http://download.mozilla.org/", + annotations: new Map([["never", "never"]]), + }); // Add a bookmark // Bookmarked page should have history cleared and frecency = -1 diff --git a/toolkit/components/places/tests/unit/test_telemetry.js b/toolkit/components/places/tests/unit/test_telemetry.js index 1a93fc99ddfc..d55a82bdde8d 100644 --- a/toolkit/components/places/tests/unit/test_telemetry.js +++ b/toolkit/components/places/tests/unit/test_telemetry.js @@ -91,8 +91,10 @@ add_task(async function test_execute() { PlacesUtils.annotations.setItemAnnotation(itemId, "test-anno", content, 0, PlacesUtils.annotations.EXPIRE_NEVER); - PlacesUtils.annotations.setPageAnnotation(uri, "test-anno", content, 0, - PlacesUtils.annotations.EXPIRE_NEVER); + await PlacesUtils.history.update({ + url: uri, + annotations: new Map([["test-anno", content]]), + }); // Request to gather telemetry data. Cc["@mozilla.org/places/categoriesStarter;1"] From 3a7f519e53cc7353e5662b92842bec7479ef636c Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Tue, 31 Jul 2018 08:46:07 -0700 Subject: [PATCH 14/52] Bug 1478945 - Refactor test_xpcshell_debugging.js to use async/await instead of callbacks. r=jdescottes MozReview-Commit-ID: 3QmGlX70BVz --HG-- extra : rebase_source : bd1fd6ab4455707aadd51738d8e7bb43ff8d7b47 --- .../tests/unit/test_xpcshell_debugging.js | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/devtools/server/tests/unit/test_xpcshell_debugging.js b/devtools/server/tests/unit/test_xpcshell_debugging.js index 4881fc714152..945355c19440 100644 --- a/devtools/server/tests/unit/test_xpcshell_debugging.js +++ b/devtools/server/tests/unit/test_xpcshell_debugging.js @@ -7,7 +7,7 @@ // Test the xpcshell-test debug support. Ideally we should have this test // next to the xpcshell support code, but that's tricky... -function run_test() { +add_task(async function() { const testFile = do_get_file("xpcshell_debugging_script.js"); // _setupDebuggerServer is from xpcshell-test's head.js @@ -18,37 +18,37 @@ function run_test() { }); const transport = DebuggerServer.connectPipe(); const client = new DebuggerClient(transport); - client.connect().then(() => { - // Even though we have no tabs, listTabs gives us the chromeDebugger. - client.getProcess().then(response => { - const actor = response.form.actor; - client.attachTab(actor).then(([response, tabClient]) => { - tabClient.attachThread(null).then(([response, threadClient]) => { - threadClient.addOneTimeListener("paused", (event, packet) => { - equal(packet.why.type, "breakpoint", - "yay - hit the breakpoint at the first line in our script"); - // Resume again - next stop should be our "debugger" statement. - threadClient.addOneTimeListener("paused", (event, packet) => { - equal(packet.why.type, "debuggerStatement", - "yay - hit the 'debugger' statement in our script"); - threadClient.resume(() => { - finishClient(client); - }); - }); - threadClient.resume(); - }); - // tell the thread to do the initial resume. This would cause the - // xpcshell test harness to resume and load the file under test. - threadClient.resume(response => { - // should have been told to resume the test itself. - ok(testResumed); - // Now load our test script. - load(testFile.path); - // and our "paused" listener above should get hit. - }); - }); + await client.connect(); + // Even though we have no tabs, listTabs gives us the chromeDebugger. + const response = await client.getProcess(); + const actor = response.form.actor; + const [, tabClient] = await client.attachTab(actor); + const [, threadClient] = await tabClient.attachThread(null); + const onResumed = new Promise(resolve => { + threadClient.addOneTimeListener("paused", (event, packet) => { + equal(packet.why.type, "breakpoint", + "yay - hit the breakpoint at the first line in our script"); + // Resume again - next stop should be our "debugger" statement. + threadClient.addOneTimeListener("paused", (event, packet) => { + equal(packet.why.type, "debuggerStatement", + "yay - hit the 'debugger' statement in our script"); + threadClient.resume(resolve); }); + threadClient.resume(); }); }); - do_test_pending(); -} + + // tell the thread to do the initial resume. This would cause the + // xpcshell test harness to resume and load the file under test. + threadClient.resume(() => { + // should have been told to resume the test itself. + ok(testResumed); + // Now load our test script. + load(testFile.path); + // and our "paused" listener above should get hit. + }); + + await onResumed; + + finishClient(client); +}); From e2f52bc54216d5968b7aac607561548346d4fe79 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Tue, 31 Jul 2018 10:08:51 -0700 Subject: [PATCH 15/52] Bug 1478945 - Test global actors against xpcshell debugger server. r=jdescottes MozReview-Commit-ID: DqCkWqZJErQ --HG-- extra : rebase_source : 535f138d2faf4cee76e44f5617d6459d9d8f0705 --- .../server/tests/unit/test_xpcshell_debugging.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/devtools/server/tests/unit/test_xpcshell_debugging.js b/devtools/server/tests/unit/test_xpcshell_debugging.js index 945355c19440..47121ed02591 100644 --- a/devtools/server/tests/unit/test_xpcshell_debugging.js +++ b/devtools/server/tests/unit/test_xpcshell_debugging.js @@ -7,6 +7,8 @@ // Test the xpcshell-test debug support. Ideally we should have this test // next to the xpcshell support code, but that's tricky... +const {getDeviceFront} = require("devtools/shared/fronts/device"); + add_task(async function() { const testFile = do_get_file("xpcshell_debugging_script.js"); @@ -19,8 +21,16 @@ add_task(async function() { const transport = DebuggerServer.connectPipe(); const client = new DebuggerClient(transport); await client.connect(); - // Even though we have no tabs, listTabs gives us the chromeDebugger. + + // Ensure that global actors are available. Just test the device actor. + const rootForm = await client.mainRoot.getRoot(); + const deviceFront = await getDeviceFront(client, rootForm); + const desc = await deviceFront.getDescription(); + equal(desc.geckobuildid, Services.appinfo.platformBuildID, "device actor works"); + + // Even though we have no tabs, getProcess gives us the chromeDebugger. const response = await client.getProcess(); + const actor = response.form.actor; const [, tabClient] = await client.attachTab(actor); const [, threadClient] = await tabClient.attachThread(null); From d15761273fecbacd3dc3f4f03724e07a5724dcaf Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Mon, 30 Jul 2018 09:15:24 +0200 Subject: [PATCH 16/52] Bug 1463104 - Instrument inspection of object expansion in the Web Console with event telemetry; r=miker. This only adds the event in Events.yaml, the actual work will happen in Github. MozReview-Commit-ID: 4GDMiGxyp4U --HG-- extra : rebase_source : 7470f07be10882e731c8a7e95c2d6d28210aeba9 --- toolkit/components/telemetry/Events.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/toolkit/components/telemetry/Events.yaml b/toolkit/components/telemetry/Events.yaml index 01ca26c6cca3..2503a276c257 100644 --- a/toolkit/components/telemetry/Events.yaml +++ b/toolkit/components/telemetry/Events.yaml @@ -651,5 +651,15 @@ devtools.main: description: User has clicked "Jump to definition" icon (next to logged functions) in the web console. release_channel_collection: opt-out expiry_version: never + extra_keys: + session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123. + object_expanded: + objects: ["webconsole"] + bug_numbers: [1463104] + notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"] + record_in_processes: ["main"] + description: User has expanded an object in the web console. + release_channel_collection: opt-out + expiry_version: never extra_keys: session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123. \ No newline at end of file From 2651346286e2221ad90926d3a79e6792d7a06b3f Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Wed, 1 Aug 2018 12:25:25 +0000 Subject: [PATCH 17/52] Bug 1479972 - nsRange should ignore mutations of the DOM tree while it's cached by Selection r=smaug Selection caches an nsRange instance for saving re-allocation cost and AddMutationObserver() and RemoveMutationObserver()'s cost when its RemoveAllRangesTemporarily() is called. Then, the instance is detached from the Selection but still referring editing point. E.g., the only text node in TextEditor when its value is set. Therefore, it'll receive character data change notification and need to check whether the point is still valid with new text. However, the range will be always set new position later, i.e., immediately before going back to a part of Selection. Therefore, even if the point becomes invalid, nobody must not have any problems. This patch makes Selection make the cached range not positioned, and makes nsRange ignore any mutations when it's not positioned. Differential Revision: https://phabricator.services.mozilla.com/D2587 --HG-- extra : moz-landing-system : lando --- dom/base/Selection.cpp | 4 ++++ dom/base/Selection.h | 6 ++++++ dom/base/nsRange.cpp | 36 +++++++++++++++++++++++++++++------- dom/base/nsRange.h | 11 +++++++++++ 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/dom/base/Selection.cpp b/dom/base/Selection.cpp index 11e0870125db..ce0bc78a8c2b 100644 --- a/dom/base/Selection.cpp +++ b/dom/base/Selection.cpp @@ -2104,6 +2104,10 @@ Selection::RemoveAllRangesTemporarily() RemoveAllRanges(result); if (result.Failed()) { mCachedRange = nullptr; + } else if (mCachedRange) { + // To save the computing cost to keep valid DOM point against DOM tree + // changes, we should clear the range temporarily. + mCachedRange->ResetTemporarily(); } return result.StealNSResult(); } diff --git a/dom/base/Selection.h b/dom/base/Selection.h index 13c043800fdc..5d2c26689df8 100644 --- a/dom/base/Selection.h +++ b/dom/base/Selection.h @@ -662,6 +662,12 @@ private: // released by Clear(), RemoveAllRangesTemporarily() stores it with this. // If Collapse() is called without existing ranges, it'll reuse this range // for saving the creation cost. + // Note that while the range is cached by this, we keep the range being + // a mutation observer because it is not so cheap to register the range + // as a mutation observer again. On the other hand, we make it not + // positioned because it is not so cheap to keep valid DOM point against + // mutations. This does not cause any problems because we will set new + // DOM point when we treat it as a range of Selection again. RefPtr mCachedRange; RefPtr mFrameSelection; RefPtr mAutoScrollTimer; diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp index c3aa91249808..2bd6890734ba 100644 --- a/dom/base/nsRange.cpp +++ b/dom/base/nsRange.cpp @@ -491,9 +491,15 @@ void nsRange::CharacterDataChanged(nsIContent* aContent, const CharacterDataChangeInfo& aInfo) { + // If this is called when this is not positioned, it means that this range + // will be initialized again or destroyed soon. See Selection::mCachedRange. + if (!mIsPositioned) { + MOZ_ASSERT(mRoot); + return; + } + MOZ_ASSERT(!mNextEndRef); MOZ_ASSERT(!mNextStartRef); - MOZ_ASSERT(mIsPositioned, "shouldn't be notified if not positioned"); nsINode* newRoot = nullptr; RawRangeBoundary newStart; @@ -645,7 +651,12 @@ nsRange::CharacterDataChanged(nsIContent* aContent, void nsRange::ContentAppended(nsIContent* aFirstNewContent) { - NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned"); + // If this is called when this is not positioned, it means that this range + // will be initialized again or destroyed soon. See Selection::mCachedRange. + if (!mIsPositioned) { + MOZ_ASSERT(mRoot); + return; + } nsINode* container = aFirstNewContent->GetParentNode(); MOZ_ASSERT(container); @@ -680,7 +691,12 @@ nsRange::ContentAppended(nsIContent* aFirstNewContent) void nsRange::ContentInserted(nsIContent* aChild) { - MOZ_ASSERT(mIsPositioned, "shouldn't be notified if not positioned"); + // If this is called when this is not positioned, it means that this range + // will be initialized again or destroyed soon. See Selection::mCachedRange. + if (!mIsPositioned) { + MOZ_ASSERT(mRoot); + return; + } bool updateBoundaries = false; nsINode* container = aChild->GetParentNode(); @@ -730,7 +746,13 @@ nsRange::ContentInserted(nsIContent* aChild) void nsRange::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling) { - MOZ_ASSERT(mIsPositioned, "shouldn't be notified if not positioned"); + // If this is called when this is not positioned, it means that this range + // will be initialized again or destroyed soon. See Selection::mCachedRange. + if (!mIsPositioned) { + MOZ_ASSERT(mRoot); + return; + } + nsINode* container = aChild->GetParentNode(); MOZ_ASSERT(container); @@ -937,17 +959,17 @@ nsRange::DoSetRange(const RawRangeBoundary& aStart, nsINode* aRoot, bool aNotInsertedYet) { MOZ_ASSERT((aStart.IsSet() && aEnd.IsSet() && aRoot) || - (!aStart.IsSet() && !aEnd.IsSet() && !aRoot), + (!aStart.IsSet() && !aEnd.IsSet()), "Set all or none"); - MOZ_ASSERT(!aRoot || aNotInsertedYet || + MOZ_ASSERT(!aRoot || (!aStart.IsSet() && !aEnd.IsSet()) || aNotInsertedYet || (nsContentUtils::ContentIsDescendantOf(aStart.Container(), aRoot) && nsContentUtils::ContentIsDescendantOf(aEnd.Container(), aRoot) && aRoot == IsValidBoundary(aStart.Container()) && aRoot == IsValidBoundary(aEnd.Container())), "Wrong root"); - MOZ_ASSERT(!aRoot || + MOZ_ASSERT(!aRoot || (!aStart.IsSet() && !aEnd.IsSet()) || (aStart.Container()->IsContent() && aEnd.Container()->IsContent() && aRoot == diff --git a/dom/base/nsRange.h b/dom/base/nsRange.h index e52bb4147096..639b0108439a 100644 --- a/dom/base/nsRange.h +++ b/dom/base/nsRange.h @@ -158,6 +158,17 @@ public: nsINode* GetCommonAncestor() const; void Reset(); + /** + * ResetTemporarily() is called when Selection starts to cache the instance + * to reuse later. This method clears mStart, mEnd and mIsPositioned but + * does not clear mRoot for reducing the cost to register this as a mutation + * observer again. + */ + void ResetTemporarily() + { + DoSetRange(RawRangeBoundary(), RawRangeBoundary(), mRoot); + } + /** * SetStart() and SetEnd() sets start point or end point separately. * However, this is expensive especially when it's a range of Selection. From f5c8aa9956c445eff616e094bbf7e2dd0aef28f7 Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Mon, 30 Jul 2018 21:46:04 +0200 Subject: [PATCH 18/52] Bug 1478799 - [wdspec] Add tests for no browsing context. r=ato MozReview-Commit-ID: FE6HE3d7kb2 --HG-- extra : rebase_source : a72c7e09123c325bdef8867763e2bf8a059c05fb --- .../webdriver/tests/accept_alert/accept.py | 5 +---- .../tests/webdriver/tests/actions/key.py | 7 +++++++ .../tests/webdriver/tests/actions/mouse.py | 7 +++++++ .../tests/webdriver/tests/add_cookie/add.py | 12 ++++++++++- .../tests/webdriver/tests/back/back.py | 8 +------ .../webdriver/tests/close_window/close.py | 8 +------ .../tests/webdriver/tests/conftest.py | 4 ++++ .../tests/delete_all_cookies/delete.py | 7 ++++++- .../webdriver/tests/delete_cookie/delete.py | 5 +---- .../webdriver/tests/dismiss_alert/dismiss.py | 5 +---- .../webdriver/tests/element_clear/clear.py | 10 ++++----- .../webdriver/tests/element_click/click.py | 11 +++++++++- .../tests/element_send_keys/send_keys.py | 21 ++++++++----------- .../execute_async_script/execute_async.py | 7 ++++++- .../webdriver/tests/execute_script/execute.py | 7 ++++++- .../webdriver/tests/find_element/find.py | 16 ++++---------- .../tests/find_element_from_element/find.py | 15 +++++-------- .../webdriver/tests/find_elements/find.py | 15 +++++-------- .../tests/find_elements_from_element/find.py | 16 +++++--------- .../tests/webdriver/tests/forward/forward.py | 8 +------ .../tests/fullscreen_window/fullscreen.py | 4 +--- .../webdriver/tests/get_active_element/get.py | 10 +-------- .../webdriver/tests/get_alert_text/get.py | 5 +---- .../webdriver/tests/get_current_url/get.py | 9 +++----- .../tests/get_element_attribute/get.py | 8 +++---- .../tests/get_element_property/get.py | 9 +++----- .../tests/get_element_tag_name/get.py | 9 +++----- .../webdriver/tests/get_element_text/get.py | 10 ++++----- .../webdriver/tests/get_named_cookie/get.py | 7 ++++++- .../tests/webdriver/tests/get_title/get.py | 10 +++------ .../webdriver/tests/get_window_rect/get.py | 4 +--- .../tests/is_element_selected/selected.py | 9 +++----- .../tests/maximize_window/maximize.py | 5 +---- .../tests/minimize_window/minimize.py | 5 +---- .../webdriver/tests/navigate_to/navigate.py | 7 ++++++- .../webdriver/tests/page_source/source.py | 7 ++++++- .../tests/webdriver/tests/refresh/refresh.py | 13 +++--------- .../webdriver/tests/send_alert_text/send.py | 13 +++++------- .../webdriver/tests/set_window_rect/set.py | 4 +--- .../tests/webdriver/tests/support/fixtures.py | 13 ++++++++++++ .../webdriver/tests/switch_to_frame/switch.py | 7 ++++++- .../tests/switch_to_parent_frame/switch.py | 8 ++++++- 42 files changed, 177 insertions(+), 193 deletions(-) diff --git a/testing/web-platform/tests/webdriver/tests/accept_alert/accept.py b/testing/web-platform/tests/webdriver/tests/accept_alert/accept.py index ef52b036c491..a111f103bf14 100644 --- a/testing/web-platform/tests/webdriver/tests/accept_alert/accept.py +++ b/testing/web-platform/tests/webdriver/tests/accept_alert/accept.py @@ -15,10 +15,7 @@ def test_null_response_value(session, url): assert value is None -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() - +def test_no_browsing_context(session, closed_window): response = accept_alert(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/actions/key.py b/testing/web-platform/tests/webdriver/tests/actions/key.py index 04d46652c1a4..50c4ed9132b1 100644 --- a/testing/web-platform/tests/webdriver/tests/actions/key.py +++ b/testing/web-platform/tests/webdriver/tests/actions/key.py @@ -1,5 +1,7 @@ import pytest +from webdriver.error import NoSuchWindowException + from tests.actions.support.keys import Keys from tests.actions.support.refine import filter_dict, get_keys, get_events @@ -12,6 +14,11 @@ def test_null_response_value(session, key_chain): assert value is None +def test_no_browsing_context(session, closed_window, key_chain): + with pytest.raises(NoSuchWindowException): + key_chain.key_up("a").perform() + + def test_lone_keyup_sends_no_events(session, key_reporter, key_chain): key_chain.key_up("a").perform() assert len(get_keys(key_reporter)) == 0 diff --git a/testing/web-platform/tests/webdriver/tests/actions/mouse.py b/testing/web-platform/tests/webdriver/tests/actions/mouse.py index acc8d9ef805e..ca8bffceb71f 100644 --- a/testing/web-platform/tests/webdriver/tests/actions/mouse.py +++ b/testing/web-platform/tests/webdriver/tests/actions/mouse.py @@ -1,5 +1,7 @@ import pytest +from webdriver.error import NoSuchWindowException + from tests.actions.support.mouse import get_inview_center, get_viewport_rect from tests.actions.support.refine import get_events, filter_dict from tests.support.asserts import assert_move_to_coordinates @@ -20,6 +22,11 @@ def test_null_response_value(session, mouse_chain): assert value is None +def test_no_browsing_context(session, closed_window, mouse_chain): + with pytest.raises(NoSuchWindowException): + mouse_chain.click().perform() + + def test_click_at_coordinates(session, test_actions_page, mouse_chain): div_point = { "x": 82, diff --git a/testing/web-platform/tests/webdriver/tests/add_cookie/add.py b/testing/web-platform/tests/webdriver/tests/add_cookie/add.py index 5608cb81e0a7..49b1d68e7d2b 100644 --- a/testing/web-platform/tests/webdriver/tests/add_cookie/add.py +++ b/testing/web-platform/tests/webdriver/tests/add_cookie/add.py @@ -1,6 +1,6 @@ from datetime import datetime, timedelta -from tests.support.asserts import assert_success +from tests.support.asserts import assert_error, assert_success from tests.support.fixtures import clear_all_cookies @@ -24,6 +24,16 @@ def test_null_response_value(session, url): assert value is None +def test_no_browsing_context(session, closed_window): + new_cookie = { + "name": "hello", + "value": "world", + } + + response = add_cookie(session, new_cookie) + assert_error(response, "no such window") + + def test_add_domain_cookie(session, url, server_config): new_cookie = { "name": "hello", diff --git a/testing/web-platform/tests/webdriver/tests/back/back.py b/testing/web-platform/tests/webdriver/tests/back/back.py index 0ecfccc193c6..0f94ab431ae0 100644 --- a/testing/web-platform/tests/webdriver/tests/back/back.py +++ b/testing/web-platform/tests/webdriver/tests/back/back.py @@ -16,13 +16,7 @@ def test_null_response_value(session): assert value is None -def test_no_browsing_context(session, create_window): - new_handle = create_window() - - session.window_handle = new_handle - session.close() - assert new_handle not in session.handles - +def test_no_browsing_context(session, closed_window): response = back(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/close_window/close.py b/testing/web-platform/tests/webdriver/tests/close_window/close.py index 57f52c1b9feb..f4e3b0481d3b 100644 --- a/testing/web-platform/tests/webdriver/tests/close_window/close.py +++ b/testing/web-platform/tests/webdriver/tests/close_window/close.py @@ -10,13 +10,7 @@ def close(session): "DELETE", "session/{session_id}/window".format(**vars(session))) -def test_no_browsing_context(session, create_window): - new_handle = create_window() - - session.window_handle = new_handle - session.close() - assert new_handle not in session.handles - +def test_no_browsing_context(session, closed_window): response = close(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/conftest.py b/testing/web-platform/tests/webdriver/tests/conftest.py index debf6fc5bc20..c39671797f6b 100644 --- a/testing/web-platform/tests/webdriver/tests/conftest.py +++ b/testing/web-platform/tests/webdriver/tests/conftest.py @@ -3,6 +3,7 @@ import pytest from tests.support.fixtures import ( add_event_listeners, configuration, + closed_window, create_cookie, create_dialog, create_frame, @@ -43,3 +44,6 @@ pytest.fixture()(http) pytest.fixture()(server_config) pytest.fixture(scope="function")(session) pytest.fixture()(url) + +# Fixtures for specific tests +pytest.fixture()(closed_window) diff --git a/testing/web-platform/tests/webdriver/tests/delete_all_cookies/delete.py b/testing/web-platform/tests/webdriver/tests/delete_all_cookies/delete.py index 363797086c92..e0947b6a7572 100644 --- a/testing/web-platform/tests/webdriver/tests/delete_all_cookies/delete.py +++ b/testing/web-platform/tests/webdriver/tests/delete_all_cookies/delete.py @@ -1,4 +1,4 @@ -from tests.support.asserts import assert_success +from tests.support.asserts import assert_error, assert_success def delete_all_cookies(session): @@ -10,3 +10,8 @@ def test_null_response_value(session, url): response = delete_all_cookies(session) value = assert_success(response) assert value is None + + +def test_no_browsing_context(session, closed_window): + response = delete_all_cookies(session) + assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/delete_cookie/delete.py b/testing/web-platform/tests/webdriver/tests/delete_cookie/delete.py index 2e79c9ba8e2c..0b6adade156c 100644 --- a/testing/web-platform/tests/webdriver/tests/delete_cookie/delete.py +++ b/testing/web-platform/tests/webdriver/tests/delete_cookie/delete.py @@ -14,10 +14,7 @@ def test_null_response_value(session, url): assert value is None -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() - +def test_no_browsing_context(session, closed_window): response = delete_cookie(session, "foo") assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/dismiss_alert/dismiss.py b/testing/web-platform/tests/webdriver/tests/dismiss_alert/dismiss.py index c2d9ad340345..c0efc38b47fd 100644 --- a/testing/web-platform/tests/webdriver/tests/dismiss_alert/dismiss.py +++ b/testing/web-platform/tests/webdriver/tests/dismiss_alert/dismiss.py @@ -15,10 +15,7 @@ def test_null_response_value(session, url): assert value is None -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() - +def test_no_browsing_context(session, closed_window): response = dismiss_alert(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/element_clear/clear.py b/testing/web-platform/tests/webdriver/tests/element_clear/clear.py index a882ba7d04ff..bc74af4b6162 100644 --- a/testing/web-platform/tests/webdriver/tests/element_clear/clear.py +++ b/testing/web-platform/tests/webdriver/tests/element_clear/clear.py @@ -2,6 +2,8 @@ import pytest +from webdriver import Element + from tests.support.asserts import ( assert_element_has_focus, assert_error, @@ -44,12 +46,8 @@ def test_null_response_value(session): assert value is None -def test_closed_context(session, create_window): - new_window = create_window() - session.window_handle = new_window - session.url = inline("") - element = session.find.css("input", all=False) - session.close() +def test_no_browsing_context(session, closed_window): + element = Element("foo", session) response = element_clear(session, element) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/element_click/click.py b/testing/web-platform/tests/webdriver/tests/element_click/click.py index ca8940c7c702..4076a1a27c66 100644 --- a/testing/web-platform/tests/webdriver/tests/element_click/click.py +++ b/testing/web-platform/tests/webdriver/tests/element_click/click.py @@ -1,4 +1,6 @@ -from tests.support.asserts import assert_success +from webdriver import Element + +from tests.support.asserts import assert_error, assert_success from tests.support.inline import inline @@ -16,3 +18,10 @@ def test_null_response_value(session): response = element_click(session, element) value = assert_success(response) assert value is None + + +def test_no_browsing_context(session, closed_window): + element = Element("foo", session) + + response = element_click(session, element) + assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/element_send_keys/send_keys.py b/testing/web-platform/tests/webdriver/tests/element_send_keys/send_keys.py index e086a16332c8..0d281d7f5cb3 100644 --- a/testing/web-platform/tests/webdriver/tests/element_send_keys/send_keys.py +++ b/testing/web-platform/tests/webdriver/tests/element_send_keys/send_keys.py @@ -1,5 +1,7 @@ import pytest +from webdriver import Element + from tests.support.asserts import assert_error, assert_success from tests.support.inline import inline @@ -21,6 +23,13 @@ def test_null_response_value(session): assert value is None +def test_no_browsing_context(session, closed_window): + element = Element("foo", session) + + response = element_send_keys(session, element, "foo") + assert_error(response, "no such window") + + @pytest.mark.parametrize("value", [True, None, 1, [], {}]) def test_invalid_text_type(session, value): session.url = inline("") @@ -30,18 +39,6 @@ def test_invalid_text_type(session, value): assert_error(response, "invalid argument") -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - - session.url = inline("") - element = session.find.css("input", all=False) - - session.close() - - response = element_send_keys(session, element, "foo") - assert_error(response, "no such window") - - def test_stale_element(session): session.url = inline("") element = session.find.css("input", all=False) diff --git a/testing/web-platform/tests/webdriver/tests/execute_async_script/execute_async.py b/testing/web-platform/tests/webdriver/tests/execute_async_script/execute_async.py index f0f101128115..2b6e61543176 100644 --- a/testing/web-platform/tests/webdriver/tests/execute_async_script/execute_async.py +++ b/testing/web-platform/tests/webdriver/tests/execute_async_script/execute_async.py @@ -1,6 +1,6 @@ import pytest -from tests.support.asserts import assert_success +from tests.support.asserts import assert_error, assert_success def execute_async_script(session, script, args=None): @@ -13,6 +13,11 @@ def execute_async_script(session, script, args=None): body) +def test_no_browsing_context(session, closed_window): + response = execute_async_script(session, "argument[0](1);") + assert_error(response, "no such window") + + @pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) def test_abort_by_user_prompt(session, dialog_type): response = execute_async_script( diff --git a/testing/web-platform/tests/webdriver/tests/execute_script/execute.py b/testing/web-platform/tests/webdriver/tests/execute_script/execute.py index ffff398a071a..632d4ed8b3fd 100644 --- a/testing/web-platform/tests/webdriver/tests/execute_script/execute.py +++ b/testing/web-platform/tests/webdriver/tests/execute_script/execute.py @@ -1,6 +1,6 @@ import pytest -from tests.support.asserts import assert_success +from tests.support.asserts import assert_error, assert_success def execute_script(session, script, args=None): @@ -14,6 +14,11 @@ def execute_script(session, script, args=None): body) +def test_no_browsing_context(session, closed_window): + response = execute_script(session, "return 1;") + assert_error(response, "no such window") + + @pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) def test_abort_by_user_prompt(session, dialog_type): response = execute_script( diff --git a/testing/web-platform/tests/webdriver/tests/find_element/find.py b/testing/web-platform/tests/webdriver/tests/find_element/find.py index 7563179e2eac..ad25e78e9e47 100644 --- a/testing/web-platform/tests/webdriver/tests/find_element/find.py +++ b/testing/web-platform/tests/webdriver/tests/find_element/find.py @@ -10,7 +10,10 @@ def find_element(session, using, value): {"using": using, "value": value}) -# 12.2 Find Element +def test_no_browsing_context(session, closed_window): + response = find_element(session, "css selector", "foo") + assert_error(response, "no such window") + @pytest.mark.parametrize("using", ["a", True, None, 1, [], {}]) def test_invalid_using_argument(session, using): @@ -26,17 +29,6 @@ def test_invalid_selector_argument(session, value): assert_error(response, "invalid argument") -def test_closed_context(session, create_window): - # Step 5 - new_window = create_window() - session.window_handle = new_window - session.close() - - response = find_element(session, "css selector", "foo") - - assert_error(response, "no such window") - - @pytest.mark.parametrize("using,value", [("css selector", "#linkText"), ("link text", "full link text"), diff --git a/testing/web-platform/tests/webdriver/tests/find_element_from_element/find.py b/testing/web-platform/tests/webdriver/tests/find_element_from_element/find.py index d5713b36aee6..d44fbb3957bc 100644 --- a/testing/web-platform/tests/webdriver/tests/find_element_from_element/find.py +++ b/testing/web-platform/tests/webdriver/tests/find_element_from_element/find.py @@ -12,6 +12,11 @@ def find_element(session, element_id, using, value): {"using": using, "value": value}) +def test_no_browsing_context(session, closed_window): + response = find_element(session, "notReal", "css selector", "foo") + assert_error(response, "no such window") + + @pytest.mark.parametrize("using", ["a", True, None, 1, [], {}]) def test_invalid_using_argument(session, using): # Step 1 - 2 @@ -26,16 +31,6 @@ def test_invalid_selector_argument(session, value): assert_error(response, "invalid argument") -def test_closed_context(session, create_window): - # Step 5 - new_window = create_window() - session.window_handle = new_window - session.close() - - response = find_element(session, "notReal", "css selector", "foo") - assert_error(response, "no such window") - - @pytest.mark.parametrize("using,value", [("css selector", "#linkText"), ("link text", "full link text"), diff --git a/testing/web-platform/tests/webdriver/tests/find_elements/find.py b/testing/web-platform/tests/webdriver/tests/find_elements/find.py index 1dac2a34a2ee..f6856e9ed6ed 100644 --- a/testing/web-platform/tests/webdriver/tests/find_elements/find.py +++ b/testing/web-platform/tests/webdriver/tests/find_elements/find.py @@ -10,6 +10,11 @@ def find_elements(session, using, value): {"using": using, "value": value}) +def test_no_browsing_context(session, closed_window): + response = find_elements(session, "css selector", "foo") + assert_error(response, "no such window") + + @pytest.mark.parametrize("using", ["a", True, None, 1, [], {}]) def test_invalid_using_argument(session, using): # Step 1 - 2 @@ -24,16 +29,6 @@ def test_invalid_selector_argument(session, value): assert_error(response, "invalid argument") -def test_closed_context(session, create_window): - # Step 5 - new_window = create_window() - session.window_handle = new_window - session.close() - - response = find_elements(session, "css selector", "foo") - assert_error(response, "no such window") - - @pytest.mark.parametrize("using,value", [("css selector", "#linkText"), ("link text", "full link text"), diff --git a/testing/web-platform/tests/webdriver/tests/find_elements_from_element/find.py b/testing/web-platform/tests/webdriver/tests/find_elements_from_element/find.py index d24d45a7a44e..bcc18642c8fd 100644 --- a/testing/web-platform/tests/webdriver/tests/find_elements_from_element/find.py +++ b/testing/web-platform/tests/webdriver/tests/find_elements_from_element/find.py @@ -12,6 +12,11 @@ def find_elements(session, element_id, using, value): {"using": using, "value": value}) +def test_no_browsing_context(session, closed_window): + response = find_elements(session, "notReal", "css selector", "foo") + assert_error(response, "no such window") + + @pytest.mark.parametrize("using", [("a"), (True), (None), (1), ([]), ({})]) def test_invalid_using_argument(session, using): # Step 1 - 2 @@ -26,17 +31,6 @@ def test_invalid_selector_argument(session, value): assert_error(response, "invalid argument") -def test_closed_context(session, create_window): - # Step 5 - new_window = create_window() - session.window_handle = new_window - session.close() - - response = find_elements(session, "notReal", "css selector", "foo") - - assert_error(response, "no such window") - - @pytest.mark.parametrize("using,value", [("css selector", "#linkText"), ("link text", "full link text"), diff --git a/testing/web-platform/tests/webdriver/tests/forward/forward.py b/testing/web-platform/tests/webdriver/tests/forward/forward.py index 17d4c56ed56b..a8c7e00b88db 100644 --- a/testing/web-platform/tests/webdriver/tests/forward/forward.py +++ b/testing/web-platform/tests/webdriver/tests/forward/forward.py @@ -17,13 +17,7 @@ def test_null_response_value(session): assert value is None -def test_no_browsing_context(session, create_window): - new_handle = create_window() - - session.window_handle = new_handle - session.close() - assert new_handle not in session.handles - +def test_no_browsing_context(session, closed_window): response = forward(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/fullscreen_window/fullscreen.py b/testing/web-platform/tests/webdriver/tests/fullscreen_window/fullscreen.py index 3a7e4fa7b1d2..5391114c6767 100644 --- a/testing/web-platform/tests/webdriver/tests/fullscreen_window/fullscreen.py +++ b/testing/web-platform/tests/webdriver/tests/fullscreen_window/fullscreen.py @@ -17,9 +17,7 @@ def is_fullscreen(session): """) -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() +def test_no_browsing_context(session, closed_window): response = fullscreen(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/get_active_element/get.py b/testing/web-platform/tests/webdriver/tests/get_active_element/get.py index d13effb81f40..ac4f14d37c0b 100644 --- a/testing/web-platform/tests/webdriver/tests/get_active_element/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_active_element/get.py @@ -29,15 +29,7 @@ def assert_is_active_element(session, response): assert_same_element(session, response.body["value"], from_js) -def test_closed_context(session, create_window): - """ - > 1. If the current browsing context is no longer open, return error with - > error code no such window. - """ - new_window = create_window() - session.window_handle = new_window - session.close() - +def test_no_browsing_context(session, closed_window): response = get_active_element(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/get_alert_text/get.py b/testing/web-platform/tests/webdriver/tests/get_alert_text/get.py index 167991b5ccbb..2327abce3a4d 100644 --- a/testing/web-platform/tests/webdriver/tests/get_alert_text/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_alert_text/get.py @@ -7,10 +7,7 @@ def get_alert_text(session): "GET", "session/{session_id}/alert/text".format(**vars(session))) -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() - +def test_no_browsing_context(session, closed_window): response = get_alert_text(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/get_current_url/get.py b/testing/web-platform/tests/webdriver/tests/get_current_url/get.py index 843b426b937b..2758ba35474e 100644 --- a/testing/web-platform/tests/webdriver/tests/get_current_url/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_current_url/get.py @@ -17,12 +17,9 @@ def get_current_url(session): "GET", "session/{session_id}/url".format(**vars(session))) -def test_get_current_url_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() - - result = get_current_url(session) - assert_error(result, "no such window") +def test_no_browsing_context(session, closed_window): + response = get_current_url(session) + assert_error(response, "no such window") def test_get_current_url_matches_location(session): diff --git a/testing/web-platform/tests/webdriver/tests/get_element_attribute/get.py b/testing/web-platform/tests/webdriver/tests/get_element_attribute/get.py index 3fcc01a7ffa4..02a155bcee66 100644 --- a/testing/web-platform/tests/webdriver/tests/get_element_attribute/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_element_attribute/get.py @@ -12,12 +12,10 @@ def get_element_attribute(session, element, attr): attr=attr)) -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() +def test_no_browsing_context(session, closed_window): + response = get_element_attribute(session, "foo", "id") + assert_error(response, "no such window") - result = get_element_attribute(session, "foo", "id") - assert_error(result, "no such window") def test_element_not_found(session): # 13.2 Step 3 diff --git a/testing/web-platform/tests/webdriver/tests/get_element_property/get.py b/testing/web-platform/tests/webdriver/tests/get_element_property/get.py index f8df2822a6c3..fde0f2a0cd6d 100644 --- a/testing/web-platform/tests/webdriver/tests/get_element_property/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_element_property/get.py @@ -12,12 +12,9 @@ def get_element_property(session, element_id, prop): prop=prop)) -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() - - result = get_element_property(session, "foo", "id") - assert_error(result, "no such window") +def test_no_browsing_context(session, closed_window): + response = get_element_property(session, "foo", "id") + assert_error(response, "no such window") def test_element_not_found(session): diff --git a/testing/web-platform/tests/webdriver/tests/get_element_tag_name/get.py b/testing/web-platform/tests/webdriver/tests/get_element_tag_name/get.py index a83ac2594ba6..d705ae1118f1 100644 --- a/testing/web-platform/tests/webdriver/tests/get_element_tag_name/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_element_tag_name/get.py @@ -9,12 +9,9 @@ def get_element_tag_name(session, element_id): element_id=element_id)) -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() - - result = get_element_tag_name(session, "foo") - assert_error(result, "no such window") +def test_no_browsing_context(session, closed_window): + response = get_element_tag_name(session, "foo") + assert_error(response, "no such window") def test_element_not_found(session): diff --git a/testing/web-platform/tests/webdriver/tests/get_element_text/get.py b/testing/web-platform/tests/webdriver/tests/get_element_text/get.py index 4d1eb18a352f..9f660308bc29 100644 --- a/testing/web-platform/tests/webdriver/tests/get_element_text/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_element_text/get.py @@ -1,11 +1,6 @@ -import pytest - from tests.support.asserts import assert_error, assert_success from tests.support.inline import inline -# For failing tests, the Get Element Text end-point is used -# directly. In all other cases, the Element.text() function is used. - def get_element_text(session, element_id): return session.transport.send( @@ -14,6 +9,11 @@ def get_element_text(session, element_id): element_id=element_id)) +def test_no_browsing_context(session, closed_window): + response = get_element_text(session, "foo") + assert_error(response, "no such window") + + def test_getting_text_of_a_non_existant_element_is_an_error(session): session.url = inline("""Hello world""") diff --git a/testing/web-platform/tests/webdriver/tests/get_named_cookie/get.py b/testing/web-platform/tests/webdriver/tests/get_named_cookie/get.py index cbf7195bad8f..915f26c801b5 100644 --- a/testing/web-platform/tests/webdriver/tests/get_named_cookie/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_named_cookie/get.py @@ -1,6 +1,6 @@ from datetime import datetime, timedelta -from tests.support.asserts import assert_success +from tests.support.asserts import assert_error, assert_success from tests.support.fixtures import clear_all_cookies from tests.support.inline import inline @@ -12,6 +12,11 @@ def get_named_cookie(session, name): name=name)) +def test_no_browsing_context(session, closed_window): + response = get_named_cookie(session, "foo") + assert_error(response, "no such window") + + def test_get_named_session_cookie(session, url): session.url = url("/common/blank.html") clear_all_cookies(session) diff --git a/testing/web-platform/tests/webdriver/tests/get_title/get.py b/testing/web-platform/tests/webdriver/tests/get_title/get.py index 3b1673c3dd59..ed5b401c564e 100644 --- a/testing/web-platform/tests/webdriver/tests/get_title/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_title/get.py @@ -12,13 +12,9 @@ def get_title(session): "GET", "session/{session_id}/title".format(**vars(session))) -def test_no_browsing_context(session, create_window): - new_window = create_window() - session.window_handle = new_window - session.close() - - result = get_title(session) - assert_error(result, "no such window") +def test_no_browsing_context(session, closed_window): + response = get_title(session) + assert_error(response, "no such window") def test_title_from_top_context(session): diff --git a/testing/web-platform/tests/webdriver/tests/get_window_rect/get.py b/testing/web-platform/tests/webdriver/tests/get_window_rect/get.py index e4f01dc362b3..ee2c9eefd3f4 100644 --- a/testing/web-platform/tests/webdriver/tests/get_window_rect/get.py +++ b/testing/web-platform/tests/webdriver/tests/get_window_rect/get.py @@ -10,9 +10,7 @@ def get_window_rect(session): "GET", "session/{session_id}/window/rect".format(**vars(session))) -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() +def test_no_browsing_context(session, closed_window): response = get_window_rect(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/is_element_selected/selected.py b/testing/web-platform/tests/webdriver/tests/is_element_selected/selected.py index 0e76e2349a83..76361e50563d 100644 --- a/testing/web-platform/tests/webdriver/tests/is_element_selected/selected.py +++ b/testing/web-platform/tests/webdriver/tests/is_element_selected/selected.py @@ -21,12 +21,9 @@ def is_element_selected(session, element_id): element_id=element_id)) -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() - - result = is_element_selected(session, "foo") - assert_error(result, "no such window") +def test_no_browsing_context(session, closed_window): + response = is_element_selected(session, "foo") + assert_error(response, "no such window") def test_element_stale(session): diff --git a/testing/web-platform/tests/webdriver/tests/maximize_window/maximize.py b/testing/web-platform/tests/webdriver/tests/maximize_window/maximize.py index 4ae8cab01995..77af0b99169a 100644 --- a/testing/web-platform/tests/webdriver/tests/maximize_window/maximize.py +++ b/testing/web-platform/tests/webdriver/tests/maximize_window/maximize.py @@ -1,5 +1,4 @@ from tests.support.asserts import assert_error, assert_success -from tests.support.inline import inline def maximize(session): @@ -18,9 +17,7 @@ def is_fullscreen(session): """) -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() +def test_no_browsing_context(session, closed_window): response = maximize(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/minimize_window/minimize.py b/testing/web-platform/tests/webdriver/tests/minimize_window/minimize.py index 5c41b02fde63..be161a62e201 100644 --- a/testing/web-platform/tests/webdriver/tests/minimize_window/minimize.py +++ b/testing/web-platform/tests/webdriver/tests/minimize_window/minimize.py @@ -1,5 +1,4 @@ from tests.support.asserts import assert_error, assert_success -from tests.support.inline import inline def minimize(session): @@ -22,9 +21,7 @@ def is_minimized(session): return session.execute_script("return document.hidden") -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() +def test_no_browsing_context(session, closed_window): response = minimize(session) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/navigate_to/navigate.py b/testing/web-platform/tests/webdriver/tests/navigate_to/navigate.py index 7f5414b2b0fd..9ac1be00b84e 100644 --- a/testing/web-platform/tests/webdriver/tests/navigate_to/navigate.py +++ b/testing/web-platform/tests/webdriver/tests/navigate_to/navigate.py @@ -1,5 +1,5 @@ +from tests.support.asserts import assert_error, assert_success from tests.support.inline import inline -from tests.support.asserts import assert_success def navigate_to(session, url): @@ -12,3 +12,8 @@ def test_null_response_value(session): response = navigate_to(session, inline("
")) value = assert_success(response) assert value is None + + +def test_no_browsing_context(session, closed_window): + response = navigate_to(session, "foo") + assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/page_source/source.py b/testing/web-platform/tests/webdriver/tests/page_source/source.py index 97e4e1eff255..0deb1b46488f 100644 --- a/testing/web-platform/tests/webdriver/tests/page_source/source.py +++ b/testing/web-platform/tests/webdriver/tests/page_source/source.py @@ -1,4 +1,4 @@ -from tests.support.asserts import assert_success +from tests.support.asserts import assert_error, assert_success from tests.support.inline import inline @@ -7,6 +7,11 @@ def get_page_source(session): "GET", "session/{session_id}/source".format(**vars(session))) +def test_no_browsing_context(session, closed_window): + response = get_page_source(session) + assert_error(response, "no such window") + + def test_source_matches_outer_html(session): session.url = inline("CheesePeas") diff --git a/testing/web-platform/tests/webdriver/tests/refresh/refresh.py b/testing/web-platform/tests/webdriver/tests/refresh/refresh.py index 5d01a9157492..30bd369bba1b 100644 --- a/testing/web-platform/tests/webdriver/tests/refresh/refresh.py +++ b/testing/web-platform/tests/webdriver/tests/refresh/refresh.py @@ -19,16 +19,9 @@ def test_null_response_value(session): assert value is None -def test_no_browsing_context(session, create_window): - new_handle = create_window() - - session.window_handle = new_handle - session.close() - assert new_handle not in session.handles - - result = refresh(session) - - assert_error(result, "no such window") +def test_no_browsing_context(session, closed_window): + response = refresh(session) + assert_error(response, "no such window") def test_basic(session): diff --git a/testing/web-platform/tests/webdriver/tests/send_alert_text/send.py b/testing/web-platform/tests/webdriver/tests/send_alert_text/send.py index 06262b82c949..9d4532a190c7 100644 --- a/testing/web-platform/tests/webdriver/tests/send_alert_text/send.py +++ b/testing/web-platform/tests/webdriver/tests/send_alert_text/send.py @@ -18,6 +18,11 @@ def test_null_response_value(session, url): assert value is None +def test_no_browsing_context(session, closed_window): + response = send_alert_text(session, "foo") + assert_error(response, "no such window") + + @pytest.mark.parametrize("text", [None, {}, [], 42, True]) def test_invalid_input(session, text): session.url = inline("") @@ -25,14 +30,6 @@ def test_invalid_input(session, text): assert_error(response, "invalid argument") -def test_no_browsing_context(session, create_window): - session.window_handle = create_window() - session.close() - - response = send_alert_text(session, "Federer") - assert_error(response, "no such window") - - def test_no_user_prompt(session): response = send_alert_text(session, "Federer") assert_error(response, "no such alert") diff --git a/testing/web-platform/tests/webdriver/tests/set_window_rect/set.py b/testing/web-platform/tests/webdriver/tests/set_window_rect/set.py index 114ddff18d44..f79656817447 100644 --- a/testing/web-platform/tests/webdriver/tests/set_window_rect/set.py +++ b/testing/web-platform/tests/webdriver/tests/set_window_rect/set.py @@ -22,9 +22,7 @@ def is_fullscreen(session): """) -def test_current_top_level_browsing_context_no_longer_open(session, create_window): - session.window_handle = create_window() - session.close() +def test_no_browsing_context(session, closed_window): response = set_window_rect(session, {}) assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/support/fixtures.py b/testing/web-platform/tests/webdriver/tests/support/fixtures.py index 775b1735e7d4..b4a29968b58c 100644 --- a/testing/web-platform/tests/webdriver/tests/support/fixtures.py +++ b/testing/web-platform/tests/webdriver/tests/support/fixtures.py @@ -286,6 +286,19 @@ def clear_all_cookies(session): session.transport.send("DELETE", "session/%s/cookie" % session.session_id) +def closed_window(session, create_window): + new_handle = create_window() + original_handle = session.window_handle + + session.window_handle = new_handle + session.close() + assert new_handle not in session.handles, "Unable to close window {}".format(new_handle) + + yield new_handle + + session.window_handle = original_handle + + def is_element_in_viewport(session, element): """Check if element is outside of the viewport""" return session.execute_script(""" diff --git a/testing/web-platform/tests/webdriver/tests/switch_to_frame/switch.py b/testing/web-platform/tests/webdriver/tests/switch_to_frame/switch.py index 955bd6b936d6..403047958665 100644 --- a/testing/web-platform/tests/webdriver/tests/switch_to_frame/switch.py +++ b/testing/web-platform/tests/webdriver/tests/switch_to_frame/switch.py @@ -1,6 +1,6 @@ import webdriver.protocol as protocol -from tests.support.asserts import assert_success +from tests.support.asserts import assert_error, assert_success from tests.support.inline import inline, iframe @@ -19,3 +19,8 @@ def test_null_response_value(session): response = switch_to_frame(session, frame_element) value = assert_success(response) assert value is None + + +def test_no_browsing_context(session, closed_window): + response = switch_to_frame(session, 1) + assert_error(response, "no such window") diff --git a/testing/web-platform/tests/webdriver/tests/switch_to_parent_frame/switch.py b/testing/web-platform/tests/webdriver/tests/switch_to_parent_frame/switch.py index c5234727f2c3..6b9c90f0cd83 100644 --- a/testing/web-platform/tests/webdriver/tests/switch_to_parent_frame/switch.py +++ b/testing/web-platform/tests/webdriver/tests/switch_to_parent_frame/switch.py @@ -1,7 +1,8 @@ import pytest + from webdriver import StaleElementReferenceException -from tests.support.asserts import assert_success +from tests.support.asserts import assert_error, assert_success from tests.support.inline import inline, iframe @@ -20,6 +21,11 @@ def test_null_response_value(session): assert value is None +def test_no_browsing_context(session, closed_window): + response = switch_to_parent_frame(session) + assert_error(response, "no such window") + + def test_stale_element_from_iframe(session): session.url = inline(iframe("

foo")) frame_element = session.find.css("iframe", all=False) From 084e71fb75130bacb9f38d5d555789159899e2bd Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Wed, 1 Aug 2018 00:56:51 -0700 Subject: [PATCH 19/52] Bug 1478240 - Convert browser_dbg_multiple-windows.js to use async/await instead of callbacks. r=jdescottes MozReview-Commit-ID: Cfp8ZM59IXi --HG-- extra : rebase_source : 9407b11319555103ac9bcaca1dcfeccb656408fa --- .../mochitest/browser_dbg_multiple-windows.js | 167 +++++++----------- 1 file changed, 59 insertions(+), 108 deletions(-) diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js b/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js index d8b32b2fedb0..c88c431f1f97 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js @@ -11,153 +11,104 @@ const TAB1_URL = EXAMPLE_URL + "doc_script-switching-01.html"; const TAB2_URL = EXAMPLE_URL + "doc_script-switching-02.html"; -var gNewTab, gNewWindow; -var gClient; - -function test() { +add_task(async function() { DebuggerServer.init(); DebuggerServer.registerAllActors(); - let transport = DebuggerServer.connectPipe(); - gClient = new DebuggerClient(transport); - gClient.connect().then(([aType, aTraits]) => { - is(aType, "browser", - "Root actor should identify itself as a browser."); + const transport = DebuggerServer.connectPipe(); + const client = new DebuggerClient(transport); + const [type] = await client.connect(); + is(type, "browser", "Root actor should identify itself as a browser."); - promise.resolve(null) - .then(() => addTab(TAB1_URL)) - .then(testFirstTab) - .then(() => addWindow(TAB2_URL)) - .then(testNewWindow) - .then(testFocusFirst) - .then(testRemoveTab) - .then(() => gClient.close()) - .then(finish) - .catch(aError => { - ok(false, "Got an error: " + aError.message + "\n" + aError.stack); - }); - }); + const tab = await addTab(TAB1_URL); + await testFirstTab(client, tab); + const win = await addWindow(TAB2_URL); + await testNewWindow(client, win); + testFocusFirst(client); + await testRemoveTab(client, win, tab); + await client.close(); +}); + +async function testFirstTab(client, tab) { + ok(!!tab, "Second tab created."); + + const response = await client.listTabs(); + const targetActor = response.tabs.filter(grip => grip.url == TAB1_URL).pop(); + ok(targetActor, "Should find a target actor for the first tab."); + + is(response.selected, 1, "The first tab is selected."); } -function testFirstTab(aTab) { - let deferred = promise.defer(); +async function testNewWindow(client, win) { + ok(!!win, "Second window created."); - gNewTab = aTab; - ok(!!gNewTab, "Second tab created."); + win.focus(); - gClient.listTabs().then(aResponse => { - let targetActor = aResponse.tabs.filter(aGrip => aGrip.url == TAB1_URL).pop(); - ok(targetActor, - "Should find a target actor for the first tab."); + const topWindow = Services.wm.getMostRecentWindow("navigator:browser"); + is(topWindow, win, "The second window is on top."); - is(aResponse.selected, 1, - "The first tab is selected."); + const isActive = promise.defer(); + const isLoaded = promise.defer(); - deferred.resolve(); - }); - - return deferred.promise; -} - -function testNewWindow(aWindow) { - let deferred = promise.defer(); - - gNewWindow = aWindow; - ok(!!gNewWindow, "Second window created."); - - gNewWindow.focus(); - - let topWindow = Services.wm.getMostRecentWindow("navigator:browser"); - is(topWindow, gNewWindow, - "The second window is on top."); - - let isActive = promise.defer(); - let isLoaded = promise.defer(); - - promise.all([isActive.promise, isLoaded.promise]).then(() => { - gClient.listTabs().then(aResponse => { - is(aResponse.selected, 2, - "The second tab is selected."); - - deferred.resolve(); - }); - }); - - if (Services.focus.activeWindow != gNewWindow) { - gNewWindow.addEventListener("activate", function onActivate(aEvent) { - if (aEvent.target != gNewWindow) { + if (Services.focus.activeWindow != win) { + win.addEventListener("activate", function onActivate(event) { + if (event.target != win) { return; } - gNewWindow.removeEventListener("activate", onActivate, true); + win.removeEventListener("activate", onActivate, true); isActive.resolve(); }, true); } else { isActive.resolve(); } - let contentLocation = gNewWindow.content.location.href; + const contentLocation = win.content.location.href; if (contentLocation != TAB2_URL) { - gNewWindow.document.addEventListener("load", function onLoad(aEvent) { - if (aEvent.target.documentURI != TAB2_URL) { + win.document.addEventListener("load", function onLoad(event) { + if (event.target.documentURI != TAB2_URL) { return; } - gNewWindow.document.removeEventListener("load", onLoad, true); + win.document.removeEventListener("load", onLoad, true); isLoaded.resolve(); }, true); } else { isLoaded.resolve(); } - return deferred.promise; + await isActive.promise; + await isLoaded.promise; + const response = await client.listTabs(); + is(response.selected, 2, "The second tab is selected."); } -function testFocusFirst() { - let deferred = promise.defer(); - - once(window.content, "focus").then(() => { - gClient.listTabs().then(aResponse => { - is(aResponse.selected, 1, - "The first tab is selected after focusing on it."); - - deferred.resolve(); - }); - }); +async function testFocusFirst(client) { + const onFocus = once(window.content, "focus"); window.content.focus(); + await onFocus; - return deferred.promise; + const response = await client.listTabs(); + is(response.selected, 1, "The first tab is selected after focusing on it."); } -function testRemoveTab() { - let deferred = promise.defer(); - - gNewWindow.close(); +async function testRemoveTab(client, win, tab) { + win.close(); // give it time to close - executeSoon(function () { continue_remove_tab(deferred); }); - return deferred.promise; + await new Promise(resolve => executeSoon(resolve)); + await continue_remove_tab(client, tab); } -function continue_remove_tab(deferred) +async function continue_remove_tab(client, tab) { - removeTab(gNewTab); + removeTab(tab); - gClient.listTabs().then(aResponse => { - // Verify that tabs are no longer included in listTabs. - let foundTab1 = aResponse.tabs.some(aGrip => aGrip.url == TAB1_URL); - let foundTab2 = aResponse.tabs.some(aGrip => aGrip.url == TAB2_URL); - ok(!foundTab1, "Tab1 should be gone."); - ok(!foundTab2, "Tab2 should be gone."); + const response = await client.listTabs(); + // Verify that tabs are no longer included in listTabs. + let foundTab1 = response.tabs.some(grip => grip.url == TAB1_URL); + let foundTab2 = response.tabs.some(grip => grip.url == TAB2_URL); + ok(!foundTab1, "Tab1 should be gone."); + ok(!foundTab2, "Tab2 should be gone."); - is(aResponse.selected, 0, - "The original tab is selected."); - - deferred.resolve(); - }); + is(response.selected, 0, "The original tab is selected."); } - -registerCleanupFunction(function () { - gNewTab = null; - gNewWindow = null; - gClient = null; -}); From 42f700d5c7c84dda1dd588b60e66338e154cf48b Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Wed, 1 Aug 2018 01:38:09 -0700 Subject: [PATCH 20/52] Bug 1478240 - Enable client/debugger/test/mochitest/browser_dbg_multiple-windows.js in e10s. r=jdescottes MozReview-Commit-ID: F9Yt9Gjmwrj --HG-- extra : rebase_source : 1e4f97668849f2a615df6bb43becb3326d3b592c --- .../debugger/test/mochitest/browser.ini | 1 - .../mochitest/browser_dbg_multiple-windows.js | 52 +++++++------------ 2 files changed, 20 insertions(+), 33 deletions(-) diff --git a/devtools/client/debugger/test/mochitest/browser.ini b/devtools/client/debugger/test/mochitest/browser.ini index 4b0313c9a0d6..96b526c1a257 100644 --- a/devtools/client/debugger/test/mochitest/browser.ini +++ b/devtools/client/debugger/test/mochitest/browser.ini @@ -358,6 +358,5 @@ skip-if = e10s # TODO [browser_dbg_location-changes-04-breakpoint.js] skip-if = e10s # TODO [browser_dbg_multiple-windows.js] -skip-if = e10s # TODO [browser_dbg_navigation.js] skip-if = e10s && debug diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js b/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js index c88c431f1f97..e6dcf99fbacc 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js @@ -47,45 +47,33 @@ async function testNewWindow(client, win) { const topWindow = Services.wm.getMostRecentWindow("navigator:browser"); is(topWindow, win, "The second window is on top."); - const isActive = promise.defer(); - const isLoaded = promise.defer(); - if (Services.focus.activeWindow != win) { - win.addEventListener("activate", function onActivate(event) { - if (event.target != win) { - return; - } - win.removeEventListener("activate", onActivate, true); - isActive.resolve(); - }, true); - } else { - isActive.resolve(); + await new Promise(resolve => { + win.addEventListener("activate", function onActivate(event) { + if (event.target != win) { + return; + } + win.removeEventListener("activate", onActivate, true); + resolve(); + }, true); + }); } - const contentLocation = win.content.location.href; - if (contentLocation != TAB2_URL) { - win.document.addEventListener("load", function onLoad(event) { - if (event.target.documentURI != TAB2_URL) { - return; - } - win.document.removeEventListener("load", onLoad, true); - isLoaded.resolve(); - }, true); - } else { - isLoaded.resolve(); - } + const tab = win.gBrowser.selectedTab; + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); - await isActive.promise; - await isLoaded.promise; const response = await client.listTabs(); is(response.selected, 2, "The second tab is selected."); } async function testFocusFirst(client) { - const onFocus = once(window.content, "focus"); - - window.content.focus(); - await onFocus; + const tab = window.gBrowser.selectedTab; + await ContentTask.spawn(tab.linkedBrowser, {}, async function() { + const onFocus = new Promise(resolve => { + content.addEventListener("focus", resolve, { once: true }); + }); + await onFocus; + }); const response = await client.listTabs(); is(response.selected, 1, "The first tab is selected after focusing on it."); @@ -105,8 +93,8 @@ async function continue_remove_tab(client, tab) const response = await client.listTabs(); // Verify that tabs are no longer included in listTabs. - let foundTab1 = response.tabs.some(grip => grip.url == TAB1_URL); - let foundTab2 = response.tabs.some(grip => grip.url == TAB2_URL); + const foundTab1 = response.tabs.some(grip => grip.url == TAB1_URL); + const foundTab2 = response.tabs.some(grip => grip.url == TAB2_URL); ok(!foundTab1, "Tab1 should be gone."); ok(!foundTab2, "Tab2 should be gone."); From d53d22346cc271798ff1679092b2bf5ff25d0891 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Wed, 1 Aug 2018 00:13:17 -0700 Subject: [PATCH 21/52] Bug 1478237 - Enable client/debugger/test/mochitest/browser_dbg_listtabs-01.js in e10s. r=jdescottes MozReview-Commit-ID: AuosU1veXvX --HG-- extra : rebase_source : e53776ff4f6d67b539446539e7aac6930c932154 --- devtools/client/debugger/test/mochitest/browser.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/devtools/client/debugger/test/mochitest/browser.ini b/devtools/client/debugger/test/mochitest/browser.ini index 96b526c1a257..44dde7bc79f1 100644 --- a/devtools/client/debugger/test/mochitest/browser.ini +++ b/devtools/client/debugger/test/mochitest/browser.ini @@ -341,7 +341,6 @@ skip-if = e10s && debug skip-if = e10s && debug tags = addons [browser_dbg_listtabs-01.js] -skip-if = e10s # TODO [browser_dbg_listtabs-02.js] skip-if = true # Never worked for remote frames, needs a mock DebuggerServerConnection [browser_dbg_listtabs-03.js] From f7b3601012b0c8b50aa81cdee2fa44da006715e9 Mon Sep 17 00:00:00 2001 From: Venkatesh Pitta Date: Fri, 27 Jul 2018 11:27:22 +1000 Subject: [PATCH 22/52] Bug 1451725 - Remove deprecated WebDriver Commands r=whimboo MozReview-Commit-ID: 7PXrlwyiFvN --HG-- extra : rebase_source : cfcc1d235ea3325bd7d15242c24c8cf8362d2647 --- testing/marionette/driver.js | 54 ------------------- .../tests/unit/test_capabilities.py | 2 +- .../tests/unit/test_execute_script.py | 4 +- .../tests/unit/test_mouse_action.py | 2 +- .../tests/unit/test_session.py | 2 +- 5 files changed, 5 insertions(+), 59 deletions(-) diff --git a/testing/marionette/driver.js b/testing/marionette/driver.js index 352617fdfaaa..88a1055aabd2 100644 --- a/testing/marionette/driver.js +++ b/testing/marionette/driver.js @@ -3645,60 +3645,6 @@ GeckoDriver.prototype.commands = { "WebDriver:SwitchToShadowRoot": GeckoDriver.prototype.switchToShadowRoot, "WebDriver:SwitchToWindow": GeckoDriver.prototype.switchToWindow, "WebDriver:TakeScreenshot": GeckoDriver.prototype.takeScreenshot, - - // deprecated WebDriver commands, remove in Firefox 63 - "acceptDialog": GeckoDriver.prototype.acceptDialog, - "addCookie": GeckoDriver.prototype.addCookie, - "clearElement": GeckoDriver.prototype.clearElement, - "clickElement": GeckoDriver.prototype.clickElement, - "close": GeckoDriver.prototype.close, - "deleteAllCookies": GeckoDriver.prototype.deleteAllCookies, - "deleteCookie": GeckoDriver.prototype.deleteCookie, - "deleteSession": GeckoDriver.prototype.deleteSession, - "dismissDialog": GeckoDriver.prototype.dismissDialog, - "executeAsyncScript": GeckoDriver.prototype.executeAsyncScript, - "executeScript": GeckoDriver.prototype.executeScript, - "findElement": GeckoDriver.prototype.findElement, - "findElements": GeckoDriver.prototype.findElements, - "fullscreen": GeckoDriver.prototype.fullscreenWindow, - "getActiveElement": GeckoDriver.prototype.getActiveElement, - "getActiveFrame": GeckoDriver.prototype.getActiveFrame, - "getCookies": GeckoDriver.prototype.getCookies, - "getCurrentUrl": GeckoDriver.prototype.getCurrentUrl, - "getElementAttribute": GeckoDriver.prototype.getElementAttribute, - "getElementProperty": GeckoDriver.prototype.getElementProperty, - "getElementRect": GeckoDriver.prototype.getElementRect, - "getElementTagName": GeckoDriver.prototype.getElementTagName, - "getElementText": GeckoDriver.prototype.getElementText, - "getElementValueOfCssProperty": GeckoDriver.prototype.getElementValueOfCssProperty, - "get": GeckoDriver.prototype.get, - "getPageSource": GeckoDriver.prototype.getPageSource, - "getSessionCapabilities": GeckoDriver.prototype.getSessionCapabilities, - "getTextFromDialog": GeckoDriver.prototype.getTextFromDialog, - "getTimeouts": GeckoDriver.prototype.getTimeouts, - "getTitle": GeckoDriver.prototype.getTitle, - "getWindowHandle": GeckoDriver.prototype.getWindowHandle, - "getWindowHandles": GeckoDriver.prototype.getWindowHandles, - "getWindowRect": GeckoDriver.prototype.getWindowRect, - "goBack": GeckoDriver.prototype.goBack, - "goForward": GeckoDriver.prototype.goForward, - "isElementDisplayed": GeckoDriver.prototype.isElementDisplayed, - "isElementEnabled": GeckoDriver.prototype.isElementEnabled, - "isElementSelected": GeckoDriver.prototype.isElementSelected, - "maximizeWindow": GeckoDriver.prototype.maximizeWindow, - "newSession": GeckoDriver.prototype.newSession, - "performActions": GeckoDriver.prototype.performActions, - "refresh": GeckoDriver.prototype.refresh, - "releaseActions": GeckoDriver.prototype.releaseActions, - "sendKeysToDialog": GeckoDriver.prototype.sendKeysToDialog, - "sendKeysToElement": GeckoDriver.prototype.sendKeysToElement, - "setTimeouts": GeckoDriver.prototype.setTimeouts, - "setWindowRect": GeckoDriver.prototype.setWindowRect, - "switchToFrame": GeckoDriver.prototype.switchToFrame, - "switchToParentFrame": GeckoDriver.prototype.switchToParentFrame, - "switchToShadowRoot": GeckoDriver.prototype.switchToShadowRoot, - "switchToWindow": GeckoDriver.prototype.switchToWindow, - "takeScreenshot": GeckoDriver.prototype.takeScreenshot, }; function getOuterWindowId(win) { diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py b/testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py index d003c2f52bcf..90446f47fc87 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py @@ -154,7 +154,7 @@ class TestCapabilityMatching(MarionetteTestCase): self.marionette.start_session(caps) self.assertIn("timeouts", self.marionette.session_capabilities) self.assertDictEqual(self.marionette.session_capabilities["timeouts"], timeouts) - self.assertDictEqual(self.marionette._send_message("getTimeouts"), timeouts) + self.assertDictEqual(self.marionette._send_message("WebDriver:GetTimeouts"), timeouts) def test_unhandled_prompt_behavior(self): behaviors = [ diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_execute_script.py b/testing/marionette/harness/marionette_harness/tests/unit/test_execute_script.py index b0e3f2e084d4..9cb53f0245f0 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_execute_script.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_execute_script.py @@ -256,7 +256,7 @@ class TestExecuteContent(MarionetteTestCase): def test_lasting_side_effects(self): def send(script): return self.marionette._send_message( - "executeScript", {"script": script}, key="value") + "WebDriver:ExecuteScript", {"script": script}, key="value") send("window.foo = 1") foo = send("return window.foo") @@ -351,7 +351,7 @@ class TestExecuteContent(MarionetteTestCase): @skip_if_mobile("Modal dialogs not supported in Fennec") def test_return_value_on_alert(self): - res = self.marionette._send_message("executeScript", {"script": "alert()"}) + res = self.marionette._send_message("WebDriver:ExecuteScript", {"script": "alert()"}) self.assertIn("value", res) self.assertIsNone(res["value"]) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_mouse_action.py b/testing/marionette/harness/marionette_harness/tests/unit/test_mouse_action.py index d1267de63619..45faaf9d1477 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_mouse_action.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_mouse_action.py @@ -35,7 +35,7 @@ class Actions(object): "type": "pointer" }]} - return self.marionette._send_message("performActions", params=params) + return self.marionette._send_message("WebDriver:PerformActions", params=params) def move(self, element, x=0, y=0, duration=250): self.action_chain.append({ diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_session.py b/testing/marionette/harness/marionette_harness/tests/unit/test_session.py index 3972b70a2981..78c1fdd4b2bd 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_session.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_session.py @@ -44,7 +44,7 @@ class TestSession(MarionetteTestCase): self.marionette.start_session() self.assertTrue(isinstance(self.marionette.session_id, unicode)) with self.assertRaises(errors.SessionNotCreatedException): - self.marionette._send_message("newSession", {}) + self.marionette._send_message("WebDriver:NewSession", {}) def test_no_session(self): with self.assertRaisesRegexp(errors.MarionetteException, "Please start a session"): From f1e3e2a9005eeec8737daba7929e074ba0c04ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 25 Jul 2018 17:19:00 +0200 Subject: [PATCH 23/52] Bug 1478393 - Add AutoGeckoProfilerEntry to parsing of script in BytecodeCompiler::compileScript r=sfink MozReview-Commit-ID: 6voFaKmvZ39 --HG-- extra : rebase_source : 57c6d31337ae91d46866bd075fb914beee68862f --- js/src/frontend/BytecodeCompiler.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index a8ef22fd9dd6..9d314ca3baab 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -24,6 +24,7 @@ #include "wasm/AsmJS.h" #include "vm/EnvironmentObject-inl.h" +#include "vm/GeckoProfiler-inl.h" #include "vm/JSObject-inl.h" #include "vm/JSScript-inl.h" @@ -333,10 +334,13 @@ BytecodeCompiler::compileScript(HandleObject environment, SharedContext* sc) for (;;) { ParseNode* pn; - if (sc->isEvalContext()) - pn = parser->evalBody(sc->asEvalContext()); - else - pn = parser->globalBody(sc->asGlobalContext()); + { + AutoGeckoProfilerEntry pseudoFrame(cx, "script parsing"); + if (sc->isEvalContext()) + pn = parser->evalBody(sc->asEvalContext()); + else + pn = parser->globalBody(sc->asGlobalContext()); + } // Successfully parsed. Emit the script. if (pn) { From 3b4a18e3b8973d8aad1fdbbe5b7dfd8a96645d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 1 Aug 2018 11:53:26 +0200 Subject: [PATCH 24/52] Bug 1478393 - Add AutoGeckoProfilerEntry to emitting of script in BytecodeCompiler::compileScript r=sfink MozReview-Commit-ID: DAdx54RGQPH --HG-- extra : rebase_source : 6aa3d2bec09a83ca70be6feed90dca93858dda5f --- js/src/frontend/BytecodeCompiler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 9d314ca3baab..73529af9f0eb 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -343,6 +343,7 @@ BytecodeCompiler::compileScript(HandleObject environment, SharedContext* sc) } // Successfully parsed. Emit the script. + AutoGeckoProfilerEntry pseudoFrame(cx, "script emit"); if (pn) { if (sc->isEvalContext() && sc->hasDebuggerStatement() && !cx->helperThread()) { // If the eval'ed script contains any debugger statement, force construction From 0471de08a0563a081b535eb0eb2c4414e6af723b Mon Sep 17 00:00:00 2001 From: Thomas Wisniewski Date: Tue, 31 Jul 2018 09:49:00 -0400 Subject: [PATCH 25/52] Bug 1456421 - Align XHR username/password precedence rules with current spec. r=baku MozReview-Commit-ID: FXCFoNhCVJz --HG-- extra : rebase_source : fa9ecd5b6f04c1102fb9326291e5760c8285841d --- dom/xhr/XMLHttpRequestMainThread.cpp | 14 ++++++++------ ...uthentication-competing-names-passwords.htm.ini | 9 --------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index 4fc0a7c19867..0331c435f68b 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -1472,13 +1472,15 @@ XMLHttpRequestMainThread::Open(const nsACString& aMethod, // Step 8 nsAutoCString host; parsedURL->GetHost(host); - if (!host.IsEmpty()) { - if (!aUsername.IsVoid() || !aPassword.IsVoid()) { - Unused << NS_MutateURI(parsedURL) - .SetUsername(NS_ConvertUTF16toUTF8(aUsername)) - .SetPassword(NS_ConvertUTF16toUTF8(aPassword)) - .Finalize(parsedURL); + if (!host.IsEmpty() && (!aUsername.IsVoid() || !aPassword.IsVoid())) { + auto mutator = NS_MutateURI(parsedURL); + if (!aUsername.IsVoid()) { + mutator.SetUsername(NS_ConvertUTF16toUTF8(aUsername)); } + if (!aPassword.IsVoid()) { + mutator.SetPassword(NS_ConvertUTF16toUTF8(aPassword)); + } + Unused << mutator.Finalize(parsedURL); } // Step 9 diff --git a/testing/web-platform/meta/xhr/send-authentication-competing-names-passwords.htm.ini b/testing/web-platform/meta/xhr/send-authentication-competing-names-passwords.htm.ini index 09d251ac5c50..e30eb925d460 100644 --- a/testing/web-platform/meta/xhr/send-authentication-competing-names-passwords.htm.ini +++ b/testing/web-platform/meta/xhr/send-authentication-competing-names-passwords.htm.ini @@ -11,12 +11,3 @@ [XMLHttpRequest user/pass options: pass in URL, user/pass in open()] expected: FAIL - [XMLHttpRequest user/pass options: user in URL, pass in open()] - expected: FAIL - - [XMLHttpRequest user/pass options: user/pass in URL; user in open()] - expected: FAIL - - [XMLHttpRequest user/pass options: user/pass in URL; pass in open()] - expected: FAIL - From 25d362ba4f11751e45aae7d3ee0809c6d448f4be Mon Sep 17 00:00:00 2001 From: Imanol Fernandez Date: Mon, 30 Jul 2018 18:14:05 +0200 Subject: [PATCH 26/52] Bug 1479424 - Fix VRManager NotifyVSync not called when compositor is paused on Android; r=kip,rbarker MozReview-Commit-ID: JY8xyCSKIgv --HG-- extra : rebase_source : 8ae0ba070bba5cc03137c4053a7730ad89090e96 --- gfx/vr/gfxVRExternal.cpp | 34 ++++++++++++++++++++++++++++++++++ gfx/vr/gfxVRExternal.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/gfx/vr/gfxVRExternal.cpp b/gfx/vr/gfxVRExternal.cpp index 360ba2ea49db..544e8b53bedb 100644 --- a/gfx/vr/gfxVRExternal.cpp +++ b/gfx/vr/gfxVRExternal.cpp @@ -117,11 +117,45 @@ VRDisplayExternal::StartPresentation() mBrowserState.layerState[0].type = VRLayerType::LayerType_Stereo_Immersive; PushState(); +#if defined(MOZ_WIDGET_ANDROID) + /** + * Android compositor is paused when presentation starts. That causes VRManager::NotifyVsync() not to be called. + * We post a VRTask to call VRManager::NotifyVsync() while the compositor is paused on Android. + * VRManager::NotifyVsync() should be called constinuosly while the compositor is paused because Gecko WebVR Architecture + * relies on that to act as a "watchdog" in order to avoid render loop stalls and recover from SubmitFrame call timeouts. + */ + PostVRTask(); +#endif // TODO - Implement telemetry: // mTelemetry.mLastDroppedFrameCount = stats.m_nNumReprojectedFrames; } +#if defined(MOZ_WIDGET_ANDROID) +void +VRDisplayExternal::PostVRTask() { + MessageLoop * vrLoop = VRListenerThreadHolder::Loop(); + if (!vrLoop || !mBrowserState.presentationActive) { + return; + } + RefPtr task = NewRunnableMethod( + "VRDisplayExternal::RunVRTask", + this, + &VRDisplayExternal::RunVRTask); + VRListenerThreadHolder::Loop()->PostDelayedTask(task.forget(), 50); +} + +void +VRDisplayExternal::RunVRTask() { + if (mBrowserState.presentationActive) { + VRManager *vm = VRManager::Get(); + vm->NotifyVsync(TimeStamp::Now()); + PostVRTask(); + } +} + +#endif // defined(MOZ_WIDGET_ANDROID) + void VRDisplayExternal::StopPresentation() { diff --git a/gfx/vr/gfxVRExternal.h b/gfx/vr/gfxVRExternal.h index e25da7a7e345..f3eabaa3cbad 100644 --- a/gfx/vr/gfxVRExternal.h +++ b/gfx/vr/gfxVRExternal.h @@ -60,6 +60,8 @@ private: void PushState(bool aNotifyCond = false); #if defined(MOZ_WIDGET_ANDROID) bool PullState(const std::function& aWaitCondition = nullptr); + void PostVRTask(); + void RunVRTask(); #else bool PullState(); #endif From a923c3ade54a263ac8799d6ab6be31233d48ba9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Wed, 1 Aug 2018 15:11:26 +0000 Subject: [PATCH 27/52] Bug 1478686 - Fix cycling focus with keyboard on slotted nodes. r=jdescottes r=jdescottes Differential Revision: https://phabricator.services.mozilla.com/D2605 --HG-- extra : moz-landing-system : lando --- .../client/inspector/markup/test/browser.ini | 1 + ...markup_shadowdom_slotted_keyboard_focus.js | 72 +++++++++++++++++++ .../markup/views/slotted-node-container.js | 2 + 3 files changed, 75 insertions(+) create mode 100644 devtools/client/inspector/markup/test/browser_markup_shadowdom_slotted_keyboard_focus.js diff --git a/devtools/client/inspector/markup/test/browser.ini b/devtools/client/inspector/markup/test/browser.ini index 448c753dcc64..97c2ab1a7190 100644 --- a/devtools/client/inspector/markup/test/browser.ini +++ b/devtools/client/inspector/markup/test/browser.ini @@ -180,6 +180,7 @@ subsuite = clipboard [browser_markup_shadowdom_open_debugger.js] [browser_markup_shadowdom_shadowroot_mode.js] [browser_markup_shadowdom_show_nodes_button.js] +[browser_markup_shadowdom_slotted_keyboard_focus.js] [browser_markup_shadowdom_slotupdate.js] [browser_markup_tag_delete_whitespace_node.js] [browser_markup_tag_edit_01.js] diff --git a/devtools/client/inspector/markup/test/browser_markup_shadowdom_slotted_keyboard_focus.js b/devtools/client/inspector/markup/test/browser_markup_shadowdom_slotted_keyboard_focus.js new file mode 100644 index 000000000000..eed8dd55c17a --- /dev/null +++ b/devtools/client/inspector/markup/test/browser_markup_shadowdom_slotted_keyboard_focus.js @@ -0,0 +1,72 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that cycling focus with keyboard (via TAB key) in slotted nodes works. + +const TEST_URL = `data:text/html;charset=utf-8, + +

slot1-1
+ + + `; + +add_task(async function() { + await enableWebComponents(); + + const { inspector } = await openInspectorForURL(TEST_URL); + const { markup } = inspector; + const win = inspector.markup.doc.defaultView; + + info("Find and expand the test-component shadow DOM host."); + const hostFront = await getNodeFront("test-component", inspector); + const hostContainer = markup.getContainer(hostFront); + await expandContainer(inspector, hostContainer); + + info("Expand the shadow root"); + const shadowRootContainer = hostContainer.getChildContainers()[0]; + await expandContainer(inspector, shadowRootContainer); + + info("Expand the slot"); + const slotContainer = shadowRootContainer.getChildContainers()[0]; + await expandContainer(inspector, slotContainer); + + info("Select the slotted container for the element"); + const node = slotContainer.getChildContainers()[0].node; + const container = inspector.markup.getContainer(node, true); + await selectNode(node, inspector, "no-reason", true); + + const root = inspector.markup.getContainer(inspector.markup._rootNode); + root.elt.focus(); + const tagSpan = container.elt.querySelector(".tag"); + const revealLink = container.elt.querySelector(".reveal-link"); + + info("Hit Enter to focus on the first element"); + let tagFocused = once(tagSpan, "focus"); + EventUtils.synthesizeAndWaitKey("KEY_Enter", {}, win); + await tagFocused; + + info("Hit Tab to focus on the next element"); + const linkFocused = once(revealLink, "focus"); + EventUtils.synthesizeKey("KEY_Tab", {}, win); + await linkFocused; + + info("Hit Tab again to cycle focus to the first element"); + tagFocused = once(tagSpan, "focus"); + EventUtils.synthesizeKey("KEY_Tab", {}, win); + await tagFocused; + + ok(inspector.markup.doc.activeElement === tagSpan, + "Focus has gone back to first element"); +}); diff --git a/devtools/client/inspector/markup/views/slotted-node-container.js b/devtools/client/inspector/markup/views/slotted-node-container.js index aa284b47e866..8d0697d6e9f0 100644 --- a/devtools/client/inspector/markup/views/slotted-node-container.js +++ b/devtools/client/inspector/markup/views/slotted-node-container.js @@ -41,6 +41,8 @@ SlottedNodeContainer.prototype = extend(MarkupContainer.prototype, { }, _onKeyDown: function(event) { + MarkupContainer.prototype._onKeyDown.call(this, event); + const isActionKey = event.code == "Enter" || event.code == "Space"; if (event.target.classList.contains("reveal-link") && isActionKey) { this._revealFromSlot(); From 182e3f8445cc30496fb2815b0a3ff15810f4b153 Mon Sep 17 00:00:00 2001 From: Chris AtLee Date: Wed, 1 Aug 2018 16:00:03 +0000 Subject: [PATCH 28/52] Bug 733530: Use .tar.gz for test archives r=gps Differential Revision: https://phabricator.services.mozilla.com/D1743 --HG-- extra : moz-landing-system : lando --- layout/tools/reftest/runreftest.py | 2 +- .../mozbuild/mozbuild/action/test_archive.py | 2 +- python/mozbuild/mozbuild/artifacts.py | 48 +++++++++++++++++-- taskcluster/ci/source-test/python.yml | 8 ++-- .../scripts/periodic_file_updates.sh | 6 +-- taskcluster/taskgraph/transforms/beetmover.py | 28 +++++------ .../transforms/beetmover_repackage.py | 14 +++--- testing/marionette/doc/Testing.md | 2 +- testing/mochitest/mochitest_options.py | 2 +- .../moztest/moztest/selftest/fixtures.py | 2 +- .../mozharness/mozilla/building/buildbase.py | 2 +- .../mozharness/mozilla/testing/testbase.py | 2 +- .../scripts/android_emulator_unittest.py | 2 +- .../mozharness/scripts/desktop_unittest.py | 2 +- testing/testsuite-targets.mk | 6 +-- testing/web-platform/tests/README.md | 4 +- testing/xpcshell/remotexpcshelltests.py | 4 +- toolkit/mozapps/installer/package-name.mk | 16 +++---- 18 files changed, 96 insertions(+), 56 deletions(-) diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py index 1f7ef998207c..e9343fd1aac9 100644 --- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -933,7 +933,7 @@ def run_test_harness(parser, options): # We have to validate options.app here for the case when the mach # command is able to find it after argument parsing. This can happen - # when running from a tests.zip. + # when running from a tests archive. if not options.app: parser.error("could not find the application path, --appname must be specified") diff --git a/python/mozbuild/mozbuild/action/test_archive.py b/python/mozbuild/mozbuild/action/test_archive.py index f7815e166b8a..6602a95e1a5f 100644 --- a/python/mozbuild/mozbuild/action/test_archive.py +++ b/python/mozbuild/mozbuild/action/test_archive.py @@ -573,7 +573,7 @@ def find_files(archive): if archive == 'common': # Construct entries ensuring all our generated harness files are - # packaged in the common tests zip. + # packaged in the common tests archive. packaged_paths = set() for entry in OBJDIR_TEST_FILES.values(): pat = mozpath.join(entry['base'], entry['pattern']) diff --git a/python/mozbuild/mozbuild/artifacts.py b/python/mozbuild/mozbuild/artifacts.py index 6121aa834785..4d618d262a3e 100644 --- a/python/mozbuild/mozbuild/artifacts.py +++ b/python/mozbuild/mozbuild/artifacts.py @@ -144,7 +144,8 @@ class ArtifactJob(object): # We can tell our input is a test archive by this suffix, which happens to # be the same across platforms. - _test_archive_suffixes = ('.common.tests.zip', '.common.tests.tar.gz') + _test_zip_archive_suffix = '.common.tests.zip' + _test_tar_archive_suffix = '.common.tests.tar.gz' def __init__(self, package_re, tests_re, log=None, download_symbols=False, @@ -190,8 +191,10 @@ class ArtifactJob(object): 'found none!'.format(re=self._tests_re)) def process_artifact(self, filename, processed_filename): - if filename.endswith(ArtifactJob._test_archive_suffixes) and self._tests_re: - return self.process_tests_artifact(filename, processed_filename) + if filename.endswith(ArtifactJob._test_zip_archive_suffix) and self._tests_re: + return self.process_tests_zip_artifact(filename, processed_filename) + if filename.endswith(ArtifactJob._test_tar_archive_suffix) and self._tests_re: + return self.process_tests_tar_artifact(filename, processed_filename) if self._symbols_archive_suffix and filename.endswith(self._symbols_archive_suffix): return self.process_symbols_archive(filename, processed_filename) if self._host_bins_re: @@ -206,7 +209,7 @@ class ArtifactJob(object): def process_package_artifact(self, filename, processed_filename): raise NotImplementedError("Subclasses must specialize process_package_artifact!") - def process_tests_artifact(self, filename, processed_filename): + def process_tests_zip_artifact(self, filename, processed_filename): from mozbuild.action.test_archive import OBJDIR_TEST_FILES added_entry = False @@ -242,6 +245,43 @@ class ArtifactJob(object): 'matched an archive path.'.format( patterns=LinuxArtifactJob.test_artifact_patterns)) + def process_tests_tar_artifact(self, filename, processed_filename): + from mozbuild.action.test_archive import OBJDIR_TEST_FILES + added_entry = False + + with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer: + with tarfile.open(filename) as reader: + for filename, entry in TarFinder(filename, reader): + for pattern, (src_prefix, dest_prefix) in self.test_artifact_patterns: + if not mozpath.match(filename, pattern): + continue + + destpath = mozpath.relpath(filename, src_prefix) + destpath = mozpath.join(dest_prefix, destpath) + self.log(logging.INFO, 'artifact', + {'destpath': destpath}, + 'Adding {destpath} to processed archive') + mode = entry.mode + writer.add(destpath.encode('utf-8'), entry.open(), mode=mode) + added_entry = True + break + for files_entry in OBJDIR_TEST_FILES.values(): + origin_pattern = files_entry['pattern'] + leaf_filename = filename + if 'dest' in files_entry: + dest = files_entry['dest'] + origin_pattern = mozpath.join(dest, origin_pattern) + leaf_filename = filename[len(dest) + 1:] + if mozpath.match(filename, origin_pattern): + destpath = mozpath.join('..', files_entry['base'], leaf_filename) + mode = entry.mode + writer.add(destpath.encode('utf-8'), entry.open(), mode=mode) + + if not added_entry: + raise ValueError('Archive format changed! No pattern from "{patterns}"' + 'matched an archive path.'.format( + patterns=LinuxArtifactJob.test_artifact_patterns)) + def process_symbols_archive(self, filename, processed_filename): with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer: reader = JarReader(filename) diff --git a/taskcluster/ci/source-test/python.yml b/taskcluster/ci/source-test/python.yml index 892b70627ae5..05af7cf737a9 100644 --- a/taskcluster/ci/source-test/python.yml +++ b/taskcluster/ci/source-test/python.yml @@ -74,8 +74,8 @@ mochitest-harness: fetches: build: - target.tar.bz2 - - target.common.tests.zip>tests - - target.mochitest.tests.zip>tests + - target.common.tests.tar.gz>tests + - target.mochitest.tests.tar.gz>tests when: files-changed: - 'testing/mochitest/**' @@ -187,8 +187,8 @@ reftest-harness: fetches: build: - target.tar.bz2 - - target.common.tests.zip>tests - - target.reftest.tests.zip>tests + - target.common.tests.tar.gz>tests + - target.reftest.tests.tar.gz>tests when: files-changed: - 'layout/tools/reftest/**' diff --git a/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh b/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh index 55644111dbee..49de82f43fa2 100755 --- a/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh +++ b/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh @@ -498,15 +498,15 @@ if [ "${USE_MC}" == "true" ]; then fi BROWSER_ARCHIVE="${PRODUCT}-${VERSION}.en-US.${PLATFORM}.${PLATFORM_EXT}" -TESTS_ARCHIVE="${PRODUCT}-${VERSION}.en-US.${PLATFORM}.common.tests.zip" +TESTS_ARCHIVE="${PRODUCT}-${VERSION}.en-US.${PLATFORM}.common.tests.tar.gz" if [ "${USE_MC}" == "true" ]; then BROWSER_ARCHIVE="${PRODUCT}-${MCVERSION}.en-US.${PLATFORM}.${PLATFORM_EXT}" - TESTS_ARCHIVE="${PRODUCT}-${MCVERSION}.en-US.${PLATFORM}.common.tests.zip" + TESTS_ARCHIVE="${PRODUCT}-${MCVERSION}.en-US.${PLATFORM}.common.tests.tar.gz" fi # Simple name builds on >=53.0.0 if [ "${MAJOR_VERSION}" -ge 53 ] ; then BROWSER_ARCHIVE="target.${PLATFORM_EXT}" - TESTS_ARCHIVE="target.common.tests.zip" + TESTS_ARCHIVE="target.common.tests.tar.gz" fi # End 'remove once 52esr is off support' diff --git a/taskcluster/taskgraph/transforms/beetmover.py b/taskcluster/taskgraph/transforms/beetmover.py index 9b2bc251eef3..0bccf2e89e25 100644 --- a/taskcluster/taskgraph/transforms/beetmover.py +++ b/taskcluster/taskgraph/transforms/beetmover.py @@ -25,19 +25,19 @@ from voluptuous import Any, Required, Optional # See example in bug 1348286 _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US = [ 'buildhub.json', - "target.common.tests.zip", - "target.cppunittest.tests.zip", + "target.common.tests.tar.gz", + "target.cppunittest.tests.tar.gz", "target.crashreporter-symbols.zip", "target.json", - "target.mochitest.tests.zip", + "target.mochitest.tests.tar.gz", "target.mozinfo.json", - "target.reftest.tests.zip", - "target.talos.tests.zip", - "target.awsy.tests.zip", + "target.reftest.tests.tar.gz", + "target.talos.tests.tar.gz", + "target.awsy.tests.tar.gz", "target.test_packages.json", "target.txt", "target.web-platform.tests.tar.gz", - "target.xpcshell.tests.zip", + "target.xpcshell.tests.tar.gz", "target_info.txt", "target.jsshell.zip", "mozharness.zip", @@ -71,19 +71,19 @@ _DESKTOP_UPSTREAM_ARTIFACTS_SIGNED_L10N = [ # See example in bug 1348286 _MOBILE_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US = [ "en-US/buildhub.json", - "en-US/target.common.tests.zip", - "en-US/target.cppunittest.tests.zip", + "en-US/target.common.tests.tar.gz", + "en-US/target.cppunittest.tests.tar.gz", "en-US/target.crashreporter-symbols.zip", "en-US/target.json", - "en-US/target.mochitest.tests.zip", + "en-US/target.mochitest.tests.tar.gz", "en-US/target.mozinfo.json", - "en-US/target.reftest.tests.zip", - "en-US/target.talos.tests.zip", - "en-US/target.awsy.tests.zip", + "en-US/target.reftest.tests.tar.gz", + "en-US/target.talos.tests.tar.gz", + "en-US/target.awsy.tests.tar.gz", "en-US/target.test_packages.json", "en-US/target.txt", "en-US/target.web-platform.tests.tar.gz", - "en-US/target.xpcshell.tests.zip", + "en-US/target.xpcshell.tests.tar.gz", "en-US/target_info.txt", "en-US/mozharness.zip", "en-US/robocop.apk", diff --git a/taskcluster/taskgraph/transforms/beetmover_repackage.py b/taskcluster/taskgraph/transforms/beetmover_repackage.py index a89968e2fa07..39578d4b258c 100644 --- a/taskcluster/taskgraph/transforms/beetmover_repackage.py +++ b/taskcluster/taskgraph/transforms/beetmover_repackage.py @@ -41,19 +41,19 @@ _WINDOWS_BUILD_PLATFORMS = [ # See example in bug 1348286 _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US = [ "buildhub.json", - "target.common.tests.zip", - "target.cppunittest.tests.zip", + "target.common.tests.tar.gz", + "target.cppunittest.tests.tar.gz", "target.crashreporter-symbols.zip", "target.json", - "target.mochitest.tests.zip", + "target.mochitest.tests.tar.gz", "target.mozinfo.json", - "target.reftest.tests.zip", - "target.talos.tests.zip", - "target.awsy.tests.zip", + "target.reftest.tests.tar.gz", + "target.talos.tests.tar.gz", + "target.awsy.tests.tar.gz", "target.test_packages.json", "target.txt", "target.web-platform.tests.tar.gz", - "target.xpcshell.tests.zip", + "target.xpcshell.tests.tar.gz", "target_info.txt", "target.jsshell.zip", "mozharness.zip", diff --git a/testing/marionette/doc/Testing.md b/testing/marionette/doc/Testing.md index ebd896fe76c2..addbc728b6ae 100644 --- a/testing/marionette/doc/Testing.md +++ b/testing/marionette/doc/Testing.md @@ -186,7 +186,7 @@ possibly to run the Marionette tests _without_ a local build and with a downloaded test archive from . If you want to run tests from a downloaded test archive, you will -need to download the `target.common.tests.zip` artifact attached to +need to download the `target.common.tests.tar.gz` artifact attached to Treeherder [build jobs] `B` for your system. Extract the archive and set up the Python Marionette client and harness by executing the following command in a virtual environment: diff --git a/testing/mochitest/mochitest_options.py b/testing/mochitest/mochitest_options.py index 7d2c62dff7ee..ed7a0617ad25 100644 --- a/testing/mochitest/mochitest_options.py +++ b/testing/mochitest/mochitest_options.py @@ -758,7 +758,7 @@ class MochitestArguments(ArgumentContainer): options.testingModulesDir = p break - # Paths to specialpowers and mochijar from the tests zip. + # Paths to specialpowers and mochijar from the tests archive. options.stagedAddons = [ os.path.join(here, 'extensions', 'specialpowers'), os.path.join(here, 'mochijar'), diff --git a/testing/mozbase/moztest/moztest/selftest/fixtures.py b/testing/mozbase/moztest/moztest/selftest/fixtures.py index 2bc612038f2a..953e66ab74a8 100644 --- a/testing/mozbase/moztest/moztest/selftest/fixtures.py +++ b/testing/mozbase/moztest/moztest/selftest/fixtures.py @@ -1,7 +1,7 @@ # 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/. -"""Pytest fixtures to help set up Firefox and a tests.zip +"""Pytest fixtures to help set up Firefox and a tests archive in test harness selftests. """ diff --git a/testing/mozharness/mozharness/mozilla/building/buildbase.py b/testing/mozharness/mozharness/mozilla/building/buildbase.py index 3aa5482636d6..417255c29cc5 100755 --- a/testing/mozharness/mozharness/mozilla/building/buildbase.py +++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py @@ -89,7 +89,7 @@ class MakeUploadOutputParser(OutputParser): # key: property name, value: condition ('symbolsUrl', "m.endswith('crashreporter-symbols.zip') or " "m.endswith('crashreporter-symbols-full.zip')"), - ('testsUrl', "m.endswith(('tests.tar.bz2', 'tests.zip'))"), + ('testsUrl', "m.endswith(('tests.tar.bz2', 'tests.zip', 'tests.tar.gz'))"), ('robocopApkUrl', "m.endswith('apk') and 'robocop' in m"), ('jsshellUrl', "'jsshell-' in m and m.endswith('.zip')"), ('partialMarUrl', "m.endswith('.mar') and '.partial.' in m"), diff --git a/testing/mozharness/mozharness/mozilla/testing/testbase.py b/testing/mozharness/mozharness/mozilla/testing/testbase.py index b9451ce4b35d..9bb888c0f227 100755 --- a/testing/mozharness/mozharness/mozilla/testing/testbase.py +++ b/testing/mozharness/mozharness/mozilla/testing/testbase.py @@ -359,7 +359,7 @@ You can set this by specifying --test-url URL ] for req_file in required_files: if req_file not in unpack_dirs: - self.info("Adding '{}' for extraction from common.tests zip file" + self.info("Adding '{}' for extraction from common.tests archive" .format(req_file)) unpack_dirs.append(req_file) diff --git a/testing/mozharness/scripts/android_emulator_unittest.py b/testing/mozharness/scripts/android_emulator_unittest.py index 278fc2cf1268..329fbad8afed 100644 --- a/testing/mozharness/scripts/android_emulator_unittest.py +++ b/testing/mozharness/scripts/android_emulator_unittest.py @@ -730,7 +730,7 @@ class AndroidEmulatorTest(TestingMixin, BaseScript, MozbaseMixin, CodeCoverageMi def download_and_extract(self): """ - Download and extract fennec APK, tests.zip, host utils, and robocop (if required). + Download and extract fennec APK, tests, host utils, and robocop (if required). """ super(AndroidEmulatorTest, self).download_and_extract( suite_categories=self._query_suite_categories()) diff --git a/testing/mozharness/scripts/desktop_unittest.py b/testing/mozharness/scripts/desktop_unittest.py index 979328df112a..93a80374a8e7 100755 --- a/testing/mozharness/scripts/desktop_unittest.py +++ b/testing/mozharness/scripts/desktop_unittest.py @@ -543,7 +543,7 @@ class DesktopUnittest(TestingMixin, MercurialScript, MozbaseMixin, def download_and_extract(self): """ download and extract test zip / download installer - optimizes which subfolders to extract from tests zip + optimizes which subfolders to extract from tests archive """ c = self.config diff --git a/testing/testsuite-targets.mk b/testing/testsuite-targets.mk index c298608e1c8c..54986bc7913f 100644 --- a/testing/testsuite-targets.mk +++ b/testing/testsuite-targets.mk @@ -113,6 +113,9 @@ stage-all: stage-cppunittests endif TEST_PKGS_ZIP := \ + $(NULL) + +TEST_PKGS_TARGZ := \ common \ cppunittest \ mochitest \ @@ -121,9 +124,6 @@ TEST_PKGS_ZIP := \ raptor \ awsy \ xpcshell \ - $(NULL) - -TEST_PKGS_TARGZ := \ web-platform \ $(NULL) diff --git a/testing/web-platform/tests/README.md b/testing/web-platform/tests/README.md index c16793556735..684f4617f689 100644 --- a/testing/web-platform/tests/README.md +++ b/testing/web-platform/tests/README.md @@ -133,11 +133,11 @@ And on macOS with homebrew using: brew install nss ``` -On other platforms, download the firefox archive and common.tests.zip +On other platforms, download the firefox archive and common.tests.tar.gz archive for your platform from [Mozilla CI](https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/). -Then extract `certutil[.exe]` from the tests.zip package and +Then extract `certutil[.exe]` from the tests.tar.gz package and `libnss3[.so|.dll|.dynlib]` and put the former on your path and the latter on your library path. diff --git a/testing/xpcshell/remotexpcshelltests.py b/testing/xpcshell/remotexpcshelltests.py index b13ada0dc4c5..5d5e72f10632 100644 --- a/testing/xpcshell/remotexpcshelltests.py +++ b/testing/xpcshell/remotexpcshelltests.py @@ -537,7 +537,7 @@ def verifyRemoteOptions(parser, options): elif options['objdir']: options['localLib'] = os.path.join(options['objdir'], 'dist/bin') elif os.path.isfile(os.path.join(here, '..', 'bin', 'xpcshell')): - # assume tests are being run from a tests.zip + # assume tests are being run from a tests archive options['localLib'] = os.path.abspath(os.path.join(here, '..', 'bin')) else: parser.error("Couldn't find local library dir, specify --local-lib-dir") @@ -551,7 +551,7 @@ def verifyRemoteOptions(parser, options): else: parser.error("Couldn't find local binary dir, specify --local-bin-dir") elif os.path.isfile(os.path.join(here, '..', 'bin', 'xpcshell')): - # assume tests are being run from a tests.zip + # assume tests are being run from a tests archive options['localBin'] = os.path.abspath(os.path.join(here, '..', 'bin')) else: parser.error("Couldn't find local binary dir, specify --local-bin-dir") diff --git a/toolkit/mozapps/installer/package-name.mk b/toolkit/mozapps/installer/package-name.mk index c63289244e1d..c789c995bc54 100644 --- a/toolkit/mozapps/installer/package-name.mk +++ b/toolkit/mozapps/installer/package-name.mk @@ -94,15 +94,15 @@ MOZSEARCH_RUST_ANALYSIS_BASENAME = $(PKG_BASENAME).mozsearch-rust MOZHARNESS_PACKAGE = mozharness.zip # Test package naming -TEST_PACKAGE = $(PKG_BASENAME).common.tests.zip -CPP_TEST_PACKAGE = $(PKG_BASENAME).cppunittest.tests.zip -XPC_TEST_PACKAGE = $(PKG_BASENAME).xpcshell.tests.zip -MOCHITEST_PACKAGE = $(PKG_BASENAME).mochitest.tests.zip -REFTEST_PACKAGE = $(PKG_BASENAME).reftest.tests.zip +TEST_PACKAGE = $(PKG_BASENAME).common.tests.tar.gz +CPP_TEST_PACKAGE = $(PKG_BASENAME).cppunittest.tests.tar.gz +XPC_TEST_PACKAGE = $(PKG_BASENAME).xpcshell.tests.tar.gz +MOCHITEST_PACKAGE = $(PKG_BASENAME).mochitest.tests.tar.gz +REFTEST_PACKAGE = $(PKG_BASENAME).reftest.tests.tar.gz WP_TEST_PACKAGE = $(PKG_BASENAME).web-platform.tests.tar.gz -TALOS_PACKAGE = $(PKG_BASENAME).talos.tests.zip -AWSY_PACKAGE = $(PKG_BASENAME).awsy.tests.zip -GTEST_PACKAGE = $(PKG_BASENAME).gtest.tests.zip +TALOS_PACKAGE = $(PKG_BASENAME).talos.tests.tar.gz +AWSY_PACKAGE = $(PKG_BASENAME).awsy.tests.tar.gz +GTEST_PACKAGE = $(PKG_BASENAME).gtest.tests.tar.gz ifneq (,$(wildcard $(DIST)/bin/application.ini)) BUILDID = $(shell $(PYTHON) $(MOZILLA_DIR)/config/printconfigsetting.py $(DIST)/bin/application.ini App BuildID) From 8b155b06b15fa0fdfc1085382a4d77225cf0758b Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Wed, 1 Aug 2018 14:47:46 +0000 Subject: [PATCH 29/52] Bug 1479027 - Don't announce existing ended tracks when they have no input r=padenot Differential Revision: https://phabricator.services.mozilla.com/D2596 --HG-- extra : moz-landing-system : lando --- dom/media/MediaStreamGraph.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 23f2af359459..63bd9c057101 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -2331,6 +2331,11 @@ MediaStream::AddListenerImpl(already_AddRefed aListener) // TrackUnionStream guarantees that each of its tracks has an input track. // Other types do not implement GetInputStreamFor() and will return null. inputStream = ps->GetInputStreamFor(it->GetID()); + if (!inputStream && it->IsEnded()) { + // If this track has no input anymore we assume there's no data for the + // current iteration either and thus no need to expose it to a listener. + continue; + } MOZ_ASSERT(inputStream); inputTrackID = ps->GetInputTrackIDFor(it->GetID()); MOZ_ASSERT(IsTrackIDExplicit(inputTrackID)); From 3fa6f1c4984233f1f78608ad982697a15c30c413 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Mon, 30 Jul 2018 11:14:54 +0100 Subject: [PATCH 30/52] Bug 1478305 - For xpcshell-test head files, limit checking no-unused-vars to the local scope only. r=mossop MozReview-Commit-ID: 2m37fyF6YwD --HG-- extra : rebase_source : 523876c41599975199158700d7d53f096d25215c --- .../lib/configs/xpcshell-test.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/xpcshell-test.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/xpcshell-test.js index 944ca250e846..091c8ba140e2 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/xpcshell-test.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/xpcshell-test.js @@ -64,6 +64,20 @@ module.exports = { "uneval": false }, + "overrides": [{ + // If it is a head file, we turn off global unused variable checks, as it + // would require searching the other test files to know if they are used or not. + // This would be expensive and slow, and it isn't worth it for head files. + // We could get developers to declare as exported, but that doesn't seem worth it. + "files": "head*.js", + "rules": { + "no-unused-vars": ["error", { + "args": "none", + "vars": "local" + }] + } + }], + rules: { "mozilla/import-headjs-globals": "error", "mozilla/mark-test-function-used": "error", From 8d235f8e45b6b09b5e7cbefd5b37417919425c71 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Mon, 30 Jul 2018 10:27:36 +0100 Subject: [PATCH 31/52] Bug 1478305 - Remove unnecessary imports and fix ESLint warnings about unused variables for browser/. r=jaws MozReview-Commit-ID: 1vHR6ixePkN --HG-- extra : rebase_source : 8f9a322d1ff075ab56b81f8710df5d841839865b --- browser/components/migration/tests/unit/head_migration.js | 4 ---- .../payments/content/paymentDialogFrameScript.js | 1 - browser/extensions/formautofill/bootstrap.js | 3 ++- browser/extensions/formautofill/content/editDialog.js | 1 + browser/extensions/formautofill/content/manageDialog.js | 1 - browser/extensions/formautofill/test/unit/head.js | 7 ------- .../test/unit/test_profileAutocompleteResult.js | 1 + browser/extensions/pdfjs/content/PdfJsRegistration.jsm | 2 -- 8 files changed, 4 insertions(+), 16 deletions(-) diff --git a/browser/components/migration/tests/unit/head_migration.js b/browser/components/migration/tests/unit/head_migration.js index df185a93356d..ef341a7149f8 100644 --- a/browser/components/migration/tests/unit/head_migration.js +++ b/browser/components/migration/tests/unit/head_migration.js @@ -1,7 +1,5 @@ "use strict"; -/* exported gProfD, promiseMigration, registerFakePath, URL */ - ChromeUtils.import("resource:///modules/MigrationUtils.jsm"); ChromeUtils.import("resource://gre/modules/LoginHelper.jsm"); ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); @@ -15,10 +13,8 @@ ChromeUtils.import("resource://testing-common/PlacesTestUtils.jsm"); XPCOMUtils.defineLazyGlobalGetters(this, [ "URL" ]); -// eslint-disable-next-line no-unused-vars ChromeUtils.defineModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); -// eslint-disable-next-line no-unused-vars ChromeUtils.defineModuleGetter(this, "Sqlite", "resource://gre/modules/Sqlite.jsm"); diff --git a/browser/components/payments/content/paymentDialogFrameScript.js b/browser/components/payments/content/paymentDialogFrameScript.js index eda0dae598df..bae8c79f714b 100644 --- a/browser/components/payments/content/paymentDialogFrameScript.js +++ b/browser/components/payments/content/paymentDialogFrameScript.js @@ -19,7 +19,6 @@ /* eslint-env mozilla/frame-script */ -ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.defineModuleGetter(this, "FormAutofill", diff --git a/browser/extensions/formautofill/bootstrap.js b/browser/extensions/formautofill/bootstrap.js index b76e22c6a1fa..6d402572b678 100644 --- a/browser/extensions/formautofill/bootstrap.js +++ b/browser/extensions/formautofill/bootstrap.js @@ -126,10 +126,11 @@ function startup(data) { Services.mm.addMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup); formAutofillParent.init().catch(Cu.reportError); - /* exported FormAutofillContent */ + /* eslint-disable no-unused-vars */ Services.ppmm.loadProcessScript("data:,new " + function() { ChromeUtils.import("resource://formautofill/FormAutofillContent.jsm"); }, true); + /* eslint-enable no-unused-vars */ Services.mm.loadFrameScript("chrome://formautofill/content/FormAutofillFrameScript.js", true); } diff --git a/browser/extensions/formautofill/content/editDialog.js b/browser/extensions/formautofill/content/editDialog.js index fe5c7ccf9f3c..6e176a8341e7 100644 --- a/browser/extensions/formautofill/content/editDialog.js +++ b/browser/extensions/formautofill/content/editDialog.js @@ -7,6 +7,7 @@ "use strict"; +// eslint-disable-next-line no-unused-vars ChromeUtils.import("resource://formautofill/FormAutofill.jsm"); ChromeUtils.import("resource://formautofill/FormAutofillUtils.jsm"); diff --git a/browser/extensions/formautofill/content/manageDialog.js b/browser/extensions/formautofill/content/manageDialog.js index 3a5f216f4593..11044c8a3ea9 100644 --- a/browser/extensions/formautofill/content/manageDialog.js +++ b/browser/extensions/formautofill/content/manageDialog.js @@ -10,7 +10,6 @@ const EDIT_ADDRESS_URL = "chrome://formautofill/content/editAddress.xhtml"; const EDIT_CREDIT_CARD_URL = "chrome://formautofill/content/editCreditCard.xhtml"; ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://formautofill/FormAutofill.jsm"); ChromeUtils.defineModuleGetter(this, "CreditCard", diff --git a/browser/extensions/formautofill/test/unit/head.js b/browser/extensions/formautofill/test/unit/head.js index a7be03d980f1..28ccf14c410f 100644 --- a/browser/extensions/formautofill/test/unit/head.js +++ b/browser/extensions/formautofill/test/unit/head.js @@ -2,25 +2,18 @@ * Provides infrastructure for automated formautofill components tests. */ -/* exported getTempFile, loadFormAutofillContent, runHeuristicsTest, sinon, - * initProfileStorage, getSyncChangeCounter, objectMatches, bootstrapURI - */ - "use strict"; ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm"); ChromeUtils.import("resource://gre/modules/FormLikeFactory.jsm"); ChromeUtils.import("resource://testing-common/FileTestUtils.jsm"); ChromeUtils.import("resource://testing-common/MockDocument.jsm"); ChromeUtils.import("resource://testing-common/TestUtils.jsm"); -// eslint-disable-next-line no-unused-vars ChromeUtils.defineModuleGetter(this, "DownloadPaths", "resource://gre/modules/DownloadPaths.jsm"); -// eslint-disable-next-line no-unused-vars ChromeUtils.defineModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); diff --git a/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js b/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js index 2643fe49b365..85b614d234a8 100644 --- a/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js +++ b/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js @@ -1,6 +1,7 @@ "use strict"; /* global AddressResult, CreditCardResult */ +// eslint-disable-next-line no-unused-vars ChromeUtils.import("resource://formautofill/ProfileAutoCompleteResult.jsm"); let matchingProfiles = [{ diff --git a/browser/extensions/pdfjs/content/PdfJsRegistration.jsm b/browser/extensions/pdfjs/content/PdfJsRegistration.jsm index e5a86fc6d755..cb173aab5c0f 100644 --- a/browser/extensions/pdfjs/content/PdfJsRegistration.jsm +++ b/browser/extensions/pdfjs/content/PdfJsRegistration.jsm @@ -19,8 +19,6 @@ var EXPORTED_SYMBOLS = ["PdfJsRegistration"]; const Cm = Components.manager; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); - ChromeUtils.defineModuleGetter(this, "PdfStreamConverter", "resource://pdf.js/PdfStreamConverter.jsm"); From eb3b37a169cc93d46423be1bb1c8e4ee1d210be3 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Mon, 30 Jul 2018 10:28:11 +0100 Subject: [PATCH 32/52] Bug 1478305 - Remove unnecessary ChromeUtils.import calls in dom/media. r=bwc MozReview-Commit-ID: 63NbLr7wap5 --HG-- extra : rebase_source : 424b9a938fd50965fa0dd29cef186ef189f6fda4 --- dom/media/IdpSandbox.jsm | 1 - dom/media/PeerConnectionIdp.jsm | 3 --- 2 files changed, 4 deletions(-) diff --git a/dom/media/IdpSandbox.jsm b/dom/media/IdpSandbox.jsm index 14eadcf26628..6e0b004d4c65 100644 --- a/dom/media/IdpSandbox.jsm +++ b/dom/media/IdpSandbox.jsm @@ -6,7 +6,6 @@ ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); /** This little class ensures that redirects maintain an https:// origin */ function RedirectHttpsOnly() {} diff --git a/dom/media/PeerConnectionIdp.jsm b/dom/media/PeerConnectionIdp.jsm index 41c8494d2d1c..f4582cdf8cb1 100644 --- a/dom/media/PeerConnectionIdp.jsm +++ b/dom/media/PeerConnectionIdp.jsm @@ -5,8 +5,6 @@ var EXPORTED_SYMBOLS = ["PeerConnectionIdp"]; -ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.defineModuleGetter(this, "IdpSandbox", "resource://gre/modules/media/IdpSandbox.jsm"); @@ -344,4 +342,3 @@ PeerConnectionIdp.prototype = { return this._win.Promise.race([ timeout, p ]); } }; - From 43685f06cb9dfde693e129560541f789282af643 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Mon, 30 Jul 2018 10:36:49 +0100 Subject: [PATCH 33/52] Bug 1478305 - Remove unnecessary ChromeUtils.import calls in mobile/. r=snorp MozReview-Commit-ID: 1eLC4Hutkcc --HG-- extra : rebase_source : bb56e8164e816948100cb813f84b8b17c6fab490 --- mobile/android/components/extensions/ext-browsingData.js | 2 -- mobile/android/modules/BrowserActions.jsm | 2 -- mobile/android/modules/LightweightThemeConsumer.jsm | 1 - mobile/android/modules/NetErrorHelper.jsm | 2 -- mobile/android/modules/RuntimePermissions.jsm | 2 -- mobile/android/modules/SharedPreferences.jsm | 2 -- mobile/android/modules/Snackbars.jsm | 2 -- mobile/android/modules/geckoview/GeckoViewContentModule.jsm | 1 - mobile/android/modules/geckoview/GeckoViewModule.jsm | 1 - mobile/android/modules/geckoview/GeckoViewTab.jsm | 1 - .../android/modules/geckoview/GeckoViewTrackingProtection.jsm | 1 - 11 files changed, 17 deletions(-) diff --git a/mobile/android/components/extensions/ext-browsingData.js b/mobile/android/components/extensions/ext-browsingData.js index ba9993c6cb32..3a1569cb5f0a 100644 --- a/mobile/android/components/extensions/ext-browsingData.js +++ b/mobile/android/components/extensions/ext-browsingData.js @@ -2,8 +2,6 @@ /* vim: set sts=2 sw=2 et tw=80: */ "use strict"; -ChromeUtils.import("resource://gre/modules/Task.jsm"); - ChromeUtils.defineModuleGetter(this, "Sanitizer", "resource://gre/modules/Sanitizer.jsm"); ChromeUtils.defineModuleGetter(this, "Services", diff --git a/mobile/android/modules/BrowserActions.jsm b/mobile/android/modules/BrowserActions.jsm index e32f877d6b54..4c7b6c44256a 100644 --- a/mobile/android/modules/BrowserActions.jsm +++ b/mobile/android/modules/BrowserActions.jsm @@ -4,8 +4,6 @@ "use strict"; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); -ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/Messaging.jsm"); var EXPORTED_SYMBOLS = ["BrowserActions"]; diff --git a/mobile/android/modules/LightweightThemeConsumer.jsm b/mobile/android/modules/LightweightThemeConsumer.jsm index 91a91a8e0852..4963a807e12f 100644 --- a/mobile/android/modules/LightweightThemeConsumer.jsm +++ b/mobile/android/modules/LightweightThemeConsumer.jsm @@ -6,7 +6,6 @@ var EXPORTED_SYMBOLS = ["LightweightThemeConsumer"]; ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/LightweightThemeManager.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.defineModuleGetter(this, "EventDispatcher", "resource://gre/modules/Messaging.jsm"); diff --git a/mobile/android/modules/NetErrorHelper.jsm b/mobile/android/modules/NetErrorHelper.jsm index a1039b82e197..3a5d920edd4d 100644 --- a/mobile/android/modules/NetErrorHelper.jsm +++ b/mobile/android/modules/NetErrorHelper.jsm @@ -4,7 +4,6 @@ "use strict"; ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Messaging.jsm"); ChromeUtils.import("resource://gre/modules/UITelemetry.jsm"); @@ -171,4 +170,3 @@ handlers.wifi = { } } }; - diff --git a/mobile/android/modules/RuntimePermissions.jsm b/mobile/android/modules/RuntimePermissions.jsm index f07db950b02d..62ac7caac084 100644 --- a/mobile/android/modules/RuntimePermissions.jsm +++ b/mobile/android/modules/RuntimePermissions.jsm @@ -6,8 +6,6 @@ var EXPORTED_SYMBOLS = ["RuntimePermissions"]; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); - ChromeUtils.defineModuleGetter(this, "EventDispatcher", "resource://gre/modules/Messaging.jsm"); diff --git a/mobile/android/modules/SharedPreferences.jsm b/mobile/android/modules/SharedPreferences.jsm index 4ed7963aa2fd..9b7a970b61e1 100644 --- a/mobile/android/modules/SharedPreferences.jsm +++ b/mobile/android/modules/SharedPreferences.jsm @@ -7,8 +7,6 @@ var EXPORTED_SYMBOLS = ["SharedPreferences"]; -// For adding observers. -ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/Messaging.jsm"); var Scope = Object.freeze({ diff --git a/mobile/android/modules/Snackbars.jsm b/mobile/android/modules/Snackbars.jsm index 26081182d0d7..fbd4a4503700 100644 --- a/mobile/android/modules/Snackbars.jsm +++ b/mobile/android/modules/Snackbars.jsm @@ -6,8 +6,6 @@ var EXPORTED_SYMBOLS = ["Snackbars"]; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); - ChromeUtils.defineModuleGetter(this, "EventDispatcher", "resource://gre/modules/Messaging.jsm"); const LENGTH_INDEFINITE = -2; diff --git a/mobile/android/modules/geckoview/GeckoViewContentModule.jsm b/mobile/android/modules/geckoview/GeckoViewContentModule.jsm index 77bf5612addb..4b8de5f23183 100644 --- a/mobile/android/modules/geckoview/GeckoViewContentModule.jsm +++ b/mobile/android/modules/geckoview/GeckoViewContentModule.jsm @@ -6,7 +6,6 @@ var EXPORTED_SYMBOLS = ["GeckoViewContentModule"]; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm"); GeckoViewUtils.initLogging("GeckoView.Module.[C]", this); diff --git a/mobile/android/modules/geckoview/GeckoViewModule.jsm b/mobile/android/modules/geckoview/GeckoViewModule.jsm index 289568a792bc..b375b88afe08 100644 --- a/mobile/android/modules/geckoview/GeckoViewModule.jsm +++ b/mobile/android/modules/geckoview/GeckoViewModule.jsm @@ -6,7 +6,6 @@ var EXPORTED_SYMBOLS = ["GeckoViewModule"]; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm"); GeckoViewUtils.initLogging("GeckoView.Module", this); diff --git a/mobile/android/modules/geckoview/GeckoViewTab.jsm b/mobile/android/modules/geckoview/GeckoViewTab.jsm index 807d95505f67..e46cea3e9d14 100644 --- a/mobile/android/modules/geckoview/GeckoViewTab.jsm +++ b/mobile/android/modules/geckoview/GeckoViewTab.jsm @@ -7,7 +7,6 @@ var EXPORTED_SYMBOLS = ["GeckoViewTab"]; ChromeUtils.import("resource://gre/modules/GeckoViewModule.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); // Stub BrowserApp implementation for WebExtensions support. class GeckoViewTab extends GeckoViewModule { diff --git a/mobile/android/modules/geckoview/GeckoViewTrackingProtection.jsm b/mobile/android/modules/geckoview/GeckoViewTrackingProtection.jsm index 538392e3647a..74f365718924 100644 --- a/mobile/android/modules/geckoview/GeckoViewTrackingProtection.jsm +++ b/mobile/android/modules/geckoview/GeckoViewTrackingProtection.jsm @@ -7,7 +7,6 @@ var EXPORTED_SYMBOLS = ["GeckoViewTrackingProtection"]; ChromeUtils.import("resource://gre/modules/GeckoViewModule.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); class GeckoViewTrackingProtection extends GeckoViewModule { onEnable() { From e6cf2a84d14c70a4e803f9960c83528978a775ae Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Mon, 30 Jul 2018 10:40:22 +0100 Subject: [PATCH 34/52] Bug 1478305 - Remove unnecessary ChromeUtils.import calls in testing/. r=mossop MozReview-Commit-ID: AGwzWcQ7aWM --HG-- extra : rebase_source : b575847ac13955f3cab75bb8900b6dae9fd693d5 --- testing/marionette/test/unit/test_cookie.js | 4 ++-- testing/modules/AppInfo.jsm | 2 -- testing/modules/Assert.jsm | 1 - testing/modules/MockRegistrar.jsm | 1 - testing/modules/MockRegistry.jsm | 2 -- testing/modules/TestUtils.jsm | 1 - testing/specialpowers/content/MockColorPicker.jsm | 3 --- testing/specialpowers/content/MockFilePicker.jsm | 1 - testing/specialpowers/content/MockPermissionPrompt.jsm | 2 -- testing/specialpowers/content/SpecialPowersObserver.jsm | 1 - 10 files changed, 2 insertions(+), 16 deletions(-) diff --git a/testing/marionette/test/unit/test_cookie.js b/testing/marionette/test/unit/test_cookie.js index 12d1bf031478..77340002ee63 100644 --- a/testing/marionette/test/unit/test_cookie.js +++ b/testing/marionette/test/unit/test_cookie.js @@ -40,8 +40,8 @@ cookie.manager = { }, getCookiesFromHost(host) { - let hostCookies = this.cookies.filter(cookie => cookie.host === host || - cookie.host === "." + host); + let hostCookies = this.cookies.filter(c => c.host === host || + c.host === "." + host); let nextIndex = 0; return { diff --git a/testing/modules/AppInfo.jsm b/testing/modules/AppInfo.jsm index 60d11214aeb5..45192da228c5 100644 --- a/testing/modules/AppInfo.jsm +++ b/testing/modules/AppInfo.jsm @@ -11,8 +11,6 @@ var EXPORTED_SYMBOLS = [ ]; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); - let origPlatformInfo = Cc["@mozilla.org/xre/app-info;1"] .getService(Ci.nsIPlatformInfo); diff --git a/testing/modules/Assert.jsm b/testing/modules/Assert.jsm index c993d2889594..17f9d04f8029 100644 --- a/testing/modules/Assert.jsm +++ b/testing/modules/Assert.jsm @@ -16,7 +16,6 @@ var EXPORTED_SYMBOLS = [ "Assert" ]; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm"); ChromeUtils.defineModuleGetter(this, "Promise", diff --git a/testing/modules/MockRegistrar.jsm b/testing/modules/MockRegistrar.jsm index 4abbca0816f1..5209cf31c20e 100644 --- a/testing/modules/MockRegistrar.jsm +++ b/testing/modules/MockRegistrar.jsm @@ -10,7 +10,6 @@ var EXPORTED_SYMBOLS = [ const Cm = Components.manager; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Log.jsm"); var logger = Log.repository.getLogger("MockRegistrar"); diff --git a/testing/modules/MockRegistry.jsm b/testing/modules/MockRegistry.jsm index ace6c0dac27f..686d40fac465 100644 --- a/testing/modules/MockRegistry.jsm +++ b/testing/modules/MockRegistry.jsm @@ -4,7 +4,6 @@ var EXPORTED_SYMBOLS = ["MockRegistry"]; ChromeUtils.import("resource://testing-common/MockRegistrar.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); class MockRegistry { constructor() { @@ -110,4 +109,3 @@ class MockRegistry { } } } - diff --git a/testing/modules/TestUtils.jsm b/testing/modules/TestUtils.jsm index 79f9295ca9a5..cdfbf2b061f6 100644 --- a/testing/modules/TestUtils.jsm +++ b/testing/modules/TestUtils.jsm @@ -22,7 +22,6 @@ var EXPORTED_SYMBOLS = [ "TestUtils", ]; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/Timer.jsm"); diff --git a/testing/specialpowers/content/MockColorPicker.jsm b/testing/specialpowers/content/MockColorPicker.jsm index 150315b6ed7f..32b6455a1625 100644 --- a/testing/specialpowers/content/MockColorPicker.jsm +++ b/testing/specialpowers/content/MockColorPicker.jsm @@ -8,9 +8,6 @@ const Cm = Components.manager; const CONTRACT_ID = "@mozilla.org/colorpicker;1"; -ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); - // Allow stuff from this scope to be accessed from non-privileged scopes. This // would crash if used outside of automation. Cu.forcePermissiveCOWs(); diff --git a/testing/specialpowers/content/MockFilePicker.jsm b/testing/specialpowers/content/MockFilePicker.jsm index 61974fef5445..6b80d3639652 100644 --- a/testing/specialpowers/content/MockFilePicker.jsm +++ b/testing/specialpowers/content/MockFilePicker.jsm @@ -10,7 +10,6 @@ const CONTRACT_ID = "@mozilla.org/filepicker;1"; ChromeUtils.import("resource://gre/modules/FileUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); // Allow stuff from this scope to be accessed from non-privileged scopes. This // would crash if used outside of automation. diff --git a/testing/specialpowers/content/MockPermissionPrompt.jsm b/testing/specialpowers/content/MockPermissionPrompt.jsm index 92c3b6e69cee..abe00a86cc60 100644 --- a/testing/specialpowers/content/MockPermissionPrompt.jsm +++ b/testing/specialpowers/content/MockPermissionPrompt.jsm @@ -8,9 +8,7 @@ const Cm = Components.manager; const CONTRACT_ID = "@mozilla.org/content-permission/prompt;1"; -ChromeUtils.import("resource://gre/modules/FileUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar); var oldClassID, oldFactory; diff --git a/testing/specialpowers/content/SpecialPowersObserver.jsm b/testing/specialpowers/content/SpecialPowersObserver.jsm index 87509ea410d2..70668a16248b 100644 --- a/testing/specialpowers/content/SpecialPowersObserver.jsm +++ b/testing/specialpowers/content/SpecialPowersObserver.jsm @@ -13,7 +13,6 @@ var EXPORTED_SYMBOLS = ["SpecialPowersObserver"]; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); Cu.importGlobalProperties(["File"]); From c7192b42dfcf836a7dd242eb3601c7e7dde4b811 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Mon, 30 Jul 2018 11:04:36 +0100 Subject: [PATCH 35/52] Bug 1478305 - Remove unnecessary imports and fix ESLint warnings about unused variables for toolkit/. r=mossop MozReview-Commit-ID: CB8xT8c5E4L --HG-- extra : rebase_source : d19443e823ff4f7a6830bf97bef1257176b830af --- toolkit/components/extensions/parent/ext-tabs-base.js | 2 -- toolkit/components/extensions/test/mochitest/chrome_head.js | 2 ++ .../extensions/test/mochitest/test_ext_webrequest_auth.html | 1 - .../components/passwordmgr/test/mochitest/test_prompt_http.html | 1 + toolkit/components/passwordmgr/test/pwmgr_common.js | 2 ++ toolkit/components/satchel/formSubmitListener.js | 1 - toolkit/modules/addons/WebNavigationContent.js | 1 - toolkit/modules/addons/WebRequestContent.js | 1 - toolkit/mozapps/extensions/amWebAPI.js | 1 - toolkit/mozapps/extensions/content/extensions.js | 2 -- .../extensions/test/xpcshell/data/from_sources/bootstrap.js | 2 +- .../extensions/test/xpcshell/data/system_addons/bootstrap.js | 2 +- .../extensions/test/xpcshell/data/test_temporary/bootstrap.js | 2 +- toolkit/mozapps/extensions/test/xpcshell/test_blocklist_gfx.js | 1 - .../extensions/test/xpcshell/test_blocklist_plugin_outdated.js | 1 - .../mozapps/extensions/test/xpcshell/test_blocklistchange.js | 1 - toolkit/mozapps/extensions/test/xpcshell/test_db_path.js | 2 -- .../mozapps/extensions/test/xpcshell/test_duplicateplugins.js | 2 -- toolkit/mozapps/extensions/test/xpcshell/test_safemode.js | 2 -- toolkit/mozapps/extensions/test/xpcshell/test_softblocked.js | 1 - toolkit/mozapps/extensions/test/xpcshell/test_webextension.js | 2 -- .../extensions/test/xpcshell/test_webextension_install.js | 2 -- .../extensions/test/xpcshell/test_webextension_langpack.js | 2 -- 23 files changed, 8 insertions(+), 28 deletions(-) diff --git a/toolkit/components/extensions/parent/ext-tabs-base.js b/toolkit/components/extensions/parent/ext-tabs-base.js index b6bcd92e3852..8babc590f06b 100644 --- a/toolkit/components/extensions/parent/ext-tabs-base.js +++ b/toolkit/components/extensions/parent/ext-tabs-base.js @@ -7,8 +7,6 @@ /* globals EventEmitter */ -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); - ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"); ChromeUtils.defineModuleGetter(this, "Services", diff --git a/toolkit/components/extensions/test/mochitest/chrome_head.js b/toolkit/components/extensions/test/mochitest/chrome_head.js index 466ad224f138..64c70b505b2b 100644 --- a/toolkit/components/extensions/test/mochitest/chrome_head.js +++ b/toolkit/components/extensions/test/mochitest/chrome_head.js @@ -1,4 +1,6 @@ "use strict"; +/* eslint-disable no-unused-vars */ ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +/* eslint-enable no-unused-vars */ diff --git a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_auth.html b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_auth.html index c2bdd843484c..d67704c6b2b8 100644 --- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_auth.html +++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_auth.html @@ -130,7 +130,6 @@ add_task(async function test_webRequest_auth_nonblocking_forwardAuthPrompt2() { let chromeScript = SpecialPowers.loadChromeScript(() => { ChromeUtils.import("resource://gre/modules/Services.jsm"); - ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); let observer = channel => { if (!(channel instanceof Ci.nsIHttpChannel && channel.URI.host === "mochi.test")) { diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html index adfbc97eec35..64e93bc15d1c 100644 --- a/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html +++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html @@ -28,6 +28,7 @@ const AUTHENTICATE_PATH = new URL("authenticate.sjs", window.location.href).path let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); runInParent(() => { + // eslint-disable-next-line no-shadow const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); let login3A, login3B, login4; diff --git a/toolkit/components/passwordmgr/test/pwmgr_common.js b/toolkit/components/passwordmgr/test/pwmgr_common.js index 1dfc41dadafd..6e919b12e066 100644 --- a/toolkit/components/passwordmgr/test/pwmgr_common.js +++ b/toolkit/components/passwordmgr/test/pwmgr_common.js @@ -241,6 +241,7 @@ function dumpLogin(label, login) { } function getRecipeParent() { + // eslint-disable-next-line no-shadow var { LoginManagerParent } = SpecialPowers.Cu.import("resource://gre/modules/LoginManagerParent.jsm", {}); if (!LoginManagerParent.recipeParentPromise) { return null; @@ -457,6 +458,7 @@ if (this.addMessageListener) { }); + // eslint-disable-next-line no-shadow let { LoginHelper } = SpecialPowers.Cu.import("resource://gre/modules/LoginHelper.jsm", {}); /** * Proxy for Services.logins (nsILoginManager). diff --git a/toolkit/components/satchel/formSubmitListener.js b/toolkit/components/satchel/formSubmitListener.js index dd2c1ff34a19..e563e564768a 100644 --- a/toolkit/components/satchel/formSubmitListener.js +++ b/toolkit/components/satchel/formSubmitListener.js @@ -8,7 +8,6 @@ ChromeUtils.defineModuleGetter(this, "CreditCard", "resource://gre/modules/CreditCard.jsm"); (function() { -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); diff --git a/toolkit/modules/addons/WebNavigationContent.js b/toolkit/modules/addons/WebNavigationContent.js index 0fc1159f5eb9..6f9093cd7fb1 100644 --- a/toolkit/modules/addons/WebNavigationContent.js +++ b/toolkit/modules/addons/WebNavigationContent.js @@ -2,7 +2,6 @@ /* eslint-env mozilla/frame-script */ -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter(this, "WebNavigationFrames", diff --git a/toolkit/modules/addons/WebRequestContent.js b/toolkit/modules/addons/WebRequestContent.js index cd6fe9b231d6..6fbab3495869 100644 --- a/toolkit/modules/addons/WebRequestContent.js +++ b/toolkit/modules/addons/WebRequestContent.js @@ -7,7 +7,6 @@ "use strict"; -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter(this, "WebRequestCommon", diff --git a/toolkit/mozapps/extensions/amWebAPI.js b/toolkit/mozapps/extensions/amWebAPI.js index 57cb3e828c88..93e939f78c13 100644 --- a/toolkit/mozapps/extensions/amWebAPI.js +++ b/toolkit/mozapps/extensions/amWebAPI.js @@ -5,7 +5,6 @@ "use strict"; ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); -ChromeUtils.import("resource://gre/modules/Services.jsm"); XPCOMUtils.defineLazyPreferenceGetter(this, "WEBEXT_PERMISSION_PROMPTS", "extensions.webextPermissionPrompts", false); diff --git a/toolkit/mozapps/extensions/content/extensions.js b/toolkit/mozapps/extensions/content/extensions.js index 5f12f5d82954..e49ca7fdfdd6 100644 --- a/toolkit/mozapps/extensions/content/extensions.js +++ b/toolkit/mozapps/extensions/content/extensions.js @@ -11,9 +11,7 @@ ChromeUtils.import("resource://gre/modules/DeferredTask.jsm"); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm"); ChromeUtils.import("resource://gre/modules/AddonManager.jsm"); -ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); ChromeUtils.import("resource://gre/modules/addons/AddonRepository.jsm"); ChromeUtils.import("resource://gre/modules/addons/AddonSettings.jsm"); diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/from_sources/bootstrap.js b/toolkit/mozapps/extensions/test/xpcshell/data/from_sources/bootstrap.js index d7badd6c64f6..24d7b1d0370c 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/data/from_sources/bootstrap.js +++ b/toolkit/mozapps/extensions/test/xpcshell/data/from_sources/bootstrap.js @@ -1 +1 @@ -ChromeUtils.import("resource://xpcshell-data/BootstrapMonitor.jsm").monitor(this); +ChromeUtils.import("resource://xpcshell-data/BootstrapMonitor.jsm", {}).monitor(this); diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/system_addons/bootstrap.js b/toolkit/mozapps/extensions/test/xpcshell/data/system_addons/bootstrap.js index d7badd6c64f6..24d7b1d0370c 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/data/system_addons/bootstrap.js +++ b/toolkit/mozapps/extensions/test/xpcshell/data/system_addons/bootstrap.js @@ -1 +1 @@ -ChromeUtils.import("resource://xpcshell-data/BootstrapMonitor.jsm").monitor(this); +ChromeUtils.import("resource://xpcshell-data/BootstrapMonitor.jsm", {}).monitor(this); diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_temporary/bootstrap.js b/toolkit/mozapps/extensions/test/xpcshell/data/test_temporary/bootstrap.js index d7badd6c64f6..24d7b1d0370c 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_temporary/bootstrap.js +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_temporary/bootstrap.js @@ -1 +1 @@ -ChromeUtils.import("resource://xpcshell-data/BootstrapMonitor.jsm").monitor(this); +ChromeUtils.import("resource://xpcshell-data/BootstrapMonitor.jsm", {}).monitor(this); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_gfx.js b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_gfx.js index 4cab282a34eb..c047c91ac1c5 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_gfx.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_gfx.js @@ -1,4 +1,3 @@ -ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser"]); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_plugin_outdated.js b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_plugin_outdated.js index 4ba313c8888e..e07fae9e0401 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_plugin_outdated.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_plugin_outdated.js @@ -5,7 +5,6 @@ const Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); ChromeUtils.import("resource://testing-common/httpd.js"); -ChromeUtils.import("resource://testing-common/MockRegistrar.jsm"); const nsIBLS = Ci.nsIBlocklistService; diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_blocklistchange.js b/toolkit/mozapps/extensions/test/xpcshell/test_blocklistchange.js index c3ef9e0f66bc..4c8967b429c1 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_blocklistchange.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklistchange.js @@ -25,7 +25,6 @@ const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"; -ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); ChromeUtils.import("resource://testing-common/MockRegistrar.jsm"); // Allow insecure updates diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_db_path.js b/toolkit/mozapps/extensions/test/xpcshell/test_db_path.js index 39b47d388fad..ad2c77744489 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_db_path.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_db_path.js @@ -1,6 +1,5 @@ ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm"); -ChromeUtils.import("resource://gre/modules/FileUtils.jsm"); const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm", {}); let global = this; @@ -52,4 +51,3 @@ add_task(async function test_non_ascii_path() { Assert.ok(data.addons[1].path.startsWith(profileDir), "path property for extension installed at runtime has the proper profile directory"); }); - diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js b/toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js index 540dc0499a8c..ff428d927451 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js @@ -2,8 +2,6 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -ChromeUtils.import("resource://testing-common/MockRegistrar.jsm"); - // This verifies that duplicate plugins are coalesced and maintain their ID // across restarts. diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_safemode.js b/toolkit/mozapps/extensions/test/xpcshell/test_safemode.js index a47dee6bef06..d1fbd1d047cb 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_safemode.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_safemode.js @@ -2,8 +2,6 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); - // Tests that extensions behave correctly in safe mode var addon1 = { diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_softblocked.js b/toolkit/mozapps/extensions/test/xpcshell/test_softblocked.js index 9a512d5723ff..a778e9e927e5 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_softblocked.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_softblocked.js @@ -4,7 +4,6 @@ const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"; -ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); ChromeUtils.import("resource://testing-common/MockRegistrar.jsm"); // Allow insecure updates diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js b/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js index 277d06b481ae..a1c6f4dc2a62 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js @@ -2,8 +2,6 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); - const ID = "webextension1@tests.mozilla.org"; const profileDir = gProfD.clone(); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install.js b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install.js index c147ca701ddc..31907d39b9aa 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install.js @@ -1,6 +1,4 @@ -ChromeUtils.import("resource://gre/modules/addons/AddonSettings.jsm"); - let profileDir; add_task(async function setup() { profileDir = gProfD.clone(); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_langpack.js b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_langpack.js index 8773aabd066e..4a4696d2dea4 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_langpack.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_langpack.js @@ -2,8 +2,6 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); - const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); const { L10nRegistry } = ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm", {}); From 17b4516d3c79f6518b93d984e813464df4029f49 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Wed, 25 Jul 2018 08:50:54 +0100 Subject: [PATCH 36/52] Bug 1478305 - Update ESLint to treat ChromeUtils.import definitions as real variable definitions for single-export modules. r=mossop One minor issue with this method, is that we are unable to support exported definitions without further work. This may cause false-positives if items are exported. However, this is already the case with the other import mechanisms, and the benefits seem to be larger than the disadvantages here. MozReview-Commit-ID: 4fx2aLRBt7T --HG-- extra : rebase_source : 1e24c8d9bc2773e80c37f47feca781be53321616 --- .../lint/eslint/eslint-plugin-mozilla/lib/helpers.js | 11 +++++++++-- .../eslint/eslint-plugin-mozilla/package-lock.json | 2 +- tools/lint/eslint/eslint-plugin-mozilla/package.json | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js index bb19e519e1c2..a35e22ae340e 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js @@ -288,10 +288,17 @@ module.exports = { let globalModules = this.modulesGlobalData; if (match[1] in globalModules) { - return globalModules[match[1]].map(name => ({ name, writable: true })); + // XXX We mark as explicit when there is only one exported symbol from + // the module. For now this avoids no-unused-vars complaining in the + // cases where we import everything from a module but only use one + // of them. + let explicit = globalModules[match[1]].length == 1; + return globalModules[match[1]].map(name => ({ + name, writable: true, explicit + })); } - return [{ name: match[2], writable: true }]; + return [{ name: match[2], writable: true, explicit: true }]; } } diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json index 9b3ec97287c0..f78befcaa534 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "0.14.0", + "version": "0.15.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package.json b/tools/lint/eslint/eslint-plugin-mozilla/package.json index 221382f856c3..ea052d8e4c00 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "0.14.0", + "version": "0.15.0", "description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.", "keywords": [ "eslint", From 2c1cf0b7fd025f36c331c7d88514a7f6442d88d3 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Tue, 31 Jul 2018 10:21:57 -0700 Subject: [PATCH 37/52] Bug 1478245 - Enable client/debugger/test/mochitest/browser_dbg_target-scoped-actor-02.js in e10s. r=jdescottes MozReview-Commit-ID: JFcEgMrYDTP --HG-- extra : rebase_source : 45c8097ffa7609999c674823b532ddeb9a56e2f8 --- .../debugger/test/mochitest/browser2.ini | 1 - .../browser_dbg_target-scoped-actor-02.js | 78 +++++++------------ 2 files changed, 26 insertions(+), 53 deletions(-) diff --git a/devtools/client/debugger/test/mochitest/browser2.ini b/devtools/client/debugger/test/mochitest/browser2.ini index 7e36adf6900b..752bd11a2fc2 100644 --- a/devtools/client/debugger/test/mochitest/browser2.ini +++ b/devtools/client/debugger/test/mochitest/browser2.ini @@ -401,7 +401,6 @@ uses-unsafe-cpows = true skip-if = e10s && debug [browser_dbg_target-scoped-actor-01.js] [browser_dbg_target-scoped-actor-02.js] -skip-if = e10s # TODO [browser_dbg_terminate-on-tab-close.js] uses-unsafe-cpows = true skip-if = e10s && debug diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_target-scoped-actor-02.js b/devtools/client/debugger/test/mochitest/browser_dbg_target-scoped-actor-02.js index e19678d5d624..9c5fab84e88d 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_target-scoped-actor-02.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_target-scoped-actor-02.js @@ -10,72 +10,46 @@ const ACTORS_URL = CHROME_URL + "testactors.js"; const TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html"; -var gClient; +add_task(async function() { + await addTab(TAB_URL); -function test() { DebuggerServer.init(); DebuggerServer.registerAllActors(); - DebuggerServer.registerModule(ACTORS_URL, { + await registerActorInContentProcess(ACTORS_URL, { prefix: "testOne", constructor: "TestActor1", type: { target: true }, }); - let transport = DebuggerServer.connectPipe(); - gClient = new DebuggerClient(transport); - gClient.connect().then(([aType, aTraits]) => { - is(aType, "browser", - "Root actor should identify itself as a browser."); + const transport = DebuggerServer.connectPipe(); + const client = new DebuggerClient(transport); + const [type] = await client.connect(); + is(type, "browser", + "Root actor should identify itself as a browser."); - addTab(TAB_URL) - .then(() => attachTargetActorForUrl(gClient, TAB_URL)) - .then(testTargetScopedActor) - .then(closeTab) - .then(() => gClient.close()) - .then(finish) - .catch(aError => { - ok(false, "Got an error: " + aError.message + "\n" + aError.stack); - }); - }); -} + const [grip] = await attachTargetActorForUrl(client, TAB_URL); + await testTargetScopedActor(client, grip); + await closeTab(client, grip); + await client.close(); +}); -function testTargetScopedActor([aGrip, aResponse]) { - let deferred = promise.defer(); - - ok(aGrip.testOneActor, +async function testTargetScopedActor(client, grip) { + ok(grip.testOneActor, "Found the test target-scoped actor."); - ok(aGrip.testOneActor.includes("testOne"), + ok(grip.testOneActor.includes("testOne"), "testOneActor's actorPrefix should be used."); - gClient.request({ to: aGrip.testOneActor, type: "ping" }, aResponse => { - is(aResponse.pong, "pong", - "Actor should respond to requests."); - - deferred.resolve(aResponse.actor); - }); - - return deferred.promise; + const response = await client.request({ to: grip.testOneActor, type: "ping" }); + is(response.pong, "pong", + "Actor should respond to requests."); } -function closeTab(aTestActor) { - return removeTab(gBrowser.selectedTab).then(() => { - let deferred = promise.defer(); - - try { - gClient.request({ to: aTestActor, type: "ping" }, aResponse => { - ok(false, "testTargetScopedActor1 didn't go away with the tab."); - deferred.reject(aResponse); - }); - } catch (e) { - is(e.message, "'ping' request packet has no destination.", "testOnActor went away."); - deferred.resolve(); - } - - return deferred.promise; - }); +async function closeTab(client, grip) { + await removeTab(gBrowser.selectedTab); + await Assert.rejects( + client.request({ to: grip.testOneActor, type: "ping" }), + err => err.message === `'ping' active request packet to '${grip.testOneActor}' ` + + `can't be sent as the connection just closed.`, + "testOneActor went away."); } - -registerCleanupFunction(function () { - gClient = null; -}); From bcaadeca3f93dcc78b80629ca860b1cd1f8fc29b Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Tue, 31 Jul 2018 11:00:09 -0700 Subject: [PATCH 38/52] Bug 1478234 - Enable client/debugger/test/mochitest/browser_dbg_globalactor.js in e10s. r=jdescottes MozReview-Commit-ID: 2x8ShkxXzNF --HG-- extra : rebase_source : 24be137e7d709318b927ed8fcda7687b8b40f532 --- .../debugger/test/mochitest/browser.ini | 1 - .../test/mochitest/browser_dbg_globalactor.js | 68 +++++++++---------- 2 files changed, 31 insertions(+), 38 deletions(-) diff --git a/devtools/client/debugger/test/mochitest/browser.ini b/devtools/client/debugger/test/mochitest/browser.ini index 44dde7bc79f1..4f2ad59eda0f 100644 --- a/devtools/client/debugger/test/mochitest/browser.ini +++ b/devtools/client/debugger/test/mochitest/browser.ini @@ -317,7 +317,6 @@ skip-if = e10s && debug uses-unsafe-cpows = true skip-if = e10s && debug [browser_dbg_globalactor.js] -skip-if = e10s # TODO [browser_dbg_hide-toolbar-buttons.js] skip-if = e10s [browser_dbg_host-layout.js] diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_globalactor.js b/devtools/client/debugger/test/mochitest/browser_dbg_globalactor.js index 88ccd82c7699..3089b71d9318 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_globalactor.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_globalactor.js @@ -9,9 +9,7 @@ const ACTORS_URL = CHROME_URL + "testactors.js"; -function test() { - let gClient; - +add_task(async function() { DebuggerServer.init(); DebuggerServer.registerAllActors(); @@ -21,43 +19,39 @@ function test() { type: { global: true }, }); - let transport = DebuggerServer.connectPipe(); - gClient = new DebuggerClient(transport); - gClient.connect().then(([aType, aTraits]) => { - is(aType, "browser", - "Root actor should identify itself as a browser."); + const transport = DebuggerServer.connectPipe(); + const client = new DebuggerClient(transport); + const [type] = await client.connect(); + is(type, "browser", + "Root actor should identify itself as a browser."); - gClient.listTabs().then(aResponse => { - let globalActor = aResponse.testOneActor; - ok(globalActor, "Found the test global actor."); - ok(globalActor.includes("testOne"), - "testGlobalActor1's actorPrefix should be used."); + let response = await client.listTabs(); + const globalActor = response.testOneActor; + ok(globalActor, "Found the test global actor."); + ok(globalActor.includes("testOne"), + "testGlobalActor1's actorPrefix should be used."); - gClient.request({ to: globalActor, type: "ping" }, aResponse => { - is(aResponse.pong, "pong", "Actor should respond to requests."); + response = await client.request({ to: globalActor, type: "ping" }); + is(response.pong, "pong", "Actor should respond to requests."); - // Send another ping to see if the same actor is used. - gClient.request({ to: globalActor, type: "ping" }, aResponse => { - is(aResponse.pong, "pong", "Actor should respond to requests."); + // Send another ping to see if the same actor is used. + response = await client.request({ to: globalActor, type: "ping" }); + is(response.pong, "pong", "Actor should respond to requests."); - // Make sure that lazily-created actors are created only once. - let count = 0; - for (let connID of Object.getOwnPropertyNames(DebuggerServer._connections)) { - let conn = DebuggerServer._connections[connID]; - let actorPrefix = conn._prefix + "testOne"; - for (let pool of conn._extraPools) { - count += Object.keys(pool._actors).filter(e => { - return e.startsWith(actorPrefix); - }).length; - } - } + // Make sure that lazily-created actors are created only once. + let count = 0; + for (const connID of Object.getOwnPropertyNames(DebuggerServer._connections)) { + const conn = DebuggerServer._connections[connID]; + const actorPrefix = conn._prefix + "testOne"; + for (let pool of conn._extraPools) { + count += Object.keys(pool._actors).filter(e => { + return e.startsWith(actorPrefix); + }).length; + } + } - is(count, 1, - "Only one actor exists in all pools. One global actor."); + is(count, 1, + "Only one actor exists in all pools. One global actor."); - gClient.close().then(finish); - }); - }); - }); - }); -} + await client.close(); +}); From 8568d6adb56683f6aec73c27c382d57aef131dc9 Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Tue, 29 May 2018 17:50:05 -0700 Subject: [PATCH 39/52] Bug 1478995 - Add node toolchain repack tasks for linux, windows, and mac, r=gps MozReview-Commit-ID: 3JEghnqGdun --HG-- extra : rebase_source : 7468ee9f27ba8e6df208b317c0c944345e2d27ad --- taskcluster/ci/toolchain/linux.yml | 17 ++++++++ taskcluster/ci/toolchain/macosx.yml | 18 +++++++++ taskcluster/ci/toolchain/windows.yml | 17 ++++++++ taskcluster/scripts/misc/repack-node.sh | 53 +++++++++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100755 taskcluster/scripts/misc/repack-node.sh diff --git a/taskcluster/ci/toolchain/linux.yml b/taskcluster/ci/toolchain/linux.yml index 688088dc53d6..941dd1e89665 100755 --- a/taskcluster/ci/toolchain/linux.yml +++ b/taskcluster/ci/toolchain/linux.yml @@ -361,6 +361,23 @@ linux64-libdmg: script: build-libdmg-hfsplus.sh toolchain-artifact: public/build/dmg.tar.xz +linux64-node: + description: "Node repack toolchain build" + treeherder: + kind: build + platform: toolchains/opt + symbol: TL(node) + tier: 1 + worker-type: aws-provisioner-v1/gecko-{level}-b-linux + worker: + docker-image: {in-tree: toolchain-build} + max-run-time: 1800 + run: + using: toolchain-script + script: repack-node.sh + arguments: ['linux64'] + toolchain-artifact: public/build/node.tar.xz + linux64-android-sdk-linux-repack: description: "Android SDK (Linux) repack toolchain build" treeherder: diff --git a/taskcluster/ci/toolchain/macosx.yml b/taskcluster/ci/toolchain/macosx.yml index b388fc0ae5ef..43e3c2f04a16 100644 --- a/taskcluster/ci/toolchain/macosx.yml +++ b/taskcluster/ci/toolchain/macosx.yml @@ -111,3 +111,21 @@ macosx64-gn: toolchains: - linux64-cctools-port - linux64-clang-6 + - linux64-node + +macosx64-node: + description: "Node repack toolchain build" + treeherder: + kind: build + platform: toolchains/opt + symbol: TM(node) + tier: 1 + worker-type: aws-provisioner-v1/gecko-{level}-b-linux + worker: + docker-image: {in-tree: toolchain-build} + max-run-time: 1800 + run: + using: toolchain-script + script: repack-node.sh + arguments: ['macosx64'] + toolchain-artifact: public/build/node.tar.xz diff --git a/taskcluster/ci/toolchain/windows.yml b/taskcluster/ci/toolchain/windows.yml index 550fff85a491..6adf1dffa4de 100755 --- a/taskcluster/ci/toolchain/windows.yml +++ b/taskcluster/ci/toolchain/windows.yml @@ -168,6 +168,23 @@ win64-rust-nightly: ] toolchain-artifact: public/build/rustc.tar.bz2 +win64-node: + description: "Node repack toolchain build" + treeherder: + kind: build + platform: toolchains/opt + symbol: TW64(node) + tier: 1 + worker-type: aws-provisioner-v1/gecko-{level}-b-linux + worker: + docker-image: {in-tree: toolchain-build} + max-run-time: 1800 + run: + using: toolchain-script + script: repack-node.sh + arguments: ['win64'] + toolchain-artifact: public/build/node.tar.bz2 + win32-rust-1.28: description: "rust repack" treeherder: diff --git a/taskcluster/scripts/misc/repack-node.sh b/taskcluster/scripts/misc/repack-node.sh new file mode 100755 index 000000000000..63b6bb8e3d92 --- /dev/null +++ b/taskcluster/scripts/misc/repack-node.sh @@ -0,0 +1,53 @@ +#!/bin/bash +set -x -e -v + +# This script is for repacking Node (and NPM) from nodejs.org. + +WORKSPACE=$HOME/workspace +UPLOAD_DIR=$HOME/artifacts +SUFFIX=tar.xz +UNARCHIVE="tar xaf" +REPACK_TAR_COMPRESSION_SWITCH=J +REPACK_SUFFIX=tar.xz + +case "$1" in +linux64) + ARCH=linux-x64 + # From https://nodejs.org/dist/v8.11.3/SHASUMS256.txt.asc + SHA256SUM=08e2fcfea66746bd966ea3a89f26851f1238d96f86c33eaf6274f67fce58421a + ;; +macosx64) + ARCH=darwin-x64 + # From https://nodejs.org/dist/v8.11.3/SHASUMS256.txt.asc + SHA256SUM=7eac0bf398cb6ecf9f84dfc577ee84eee3d930f7a54b7e50f56d1a358b528792 + ;; +win64) + ARCH=win-x64 + # From https://nodejs.org/dist/v8.11.3/SHASUMS256.txt.asc + SHA256SUM=91b779def1b21dcd1def7fc9671a869a1e2f989952e76fdc08a5d73570075f31 + SUFFIX=zip + UNARCHIVE=unzip + REPACK_TAR_COMPRESSION_SWITCH=j + REPACK_SUFFIX=tar.bz2 + ;; +esac + +VERSION=8.11.3 +# From https://nodejs.org/en/download/ +URL=https://nodejs.org/dist/v$VERSION/node-v$VERSION-$ARCH.$SUFFIX +ARCHIVE=node-v$VERSION-$ARCH.$SUFFIX +DIR=node-v$VERSION + +mkdir -p $UPLOAD_DIR + +cd $WORKSPACE +wget --progress=dot:mega $URL + +# shasum is available on both Linux and Windows builders, but on +# Windows, reading from stdin doesn't work as expected. +echo "$SHA256SUM $ARCHIVE" > node.txt +shasum --algorithm 256 --check node.txt + +$UNARCHIVE $ARCHIVE +mv node-v$VERSION-$ARCH node +tar c${REPACK_TAR_COMPRESSION_SWITCH}f $UPLOAD_DIR/node.$REPACK_SUFFIX node From d2201e2b260856a5fd587c1e38c88373946470ac Mon Sep 17 00:00:00 2001 From: Dan Mosedale Date: Thu, 26 Jul 2018 13:34:44 -0700 Subject: [PATCH 40/52] Bug 1478995 - Add node toolchains to each automated build, r=gps MozReview-Commit-ID: BQCAVP0nk4S --HG-- extra : rebase_source : bcd0d3a8b26058ed3354f72d626362660bf7b5b9 --- taskcluster/ci/artifact-build/kind.yml | 2 ++ taskcluster/ci/build/android-stuff.yml | 6 ++++ taskcluster/ci/build/android.yml | 8 +++++ taskcluster/ci/build/linux.yml | 33 +++++++++++++++++++ taskcluster/ci/build/macosx.yml | 8 +++++ taskcluster/ci/build/windows.yml | 29 ++++++++++++++++ taskcluster/ci/hazard/kind.yml | 2 ++ .../ci/static-analysis-autotest/kind.yml | 2 ++ taskcluster/ci/static-analysis/kind.yml | 6 ++++ taskcluster/ci/toolchain/macosx.yml | 3 ++ taskcluster/ci/valgrind/kind.yml | 1 + taskcluster/taskgraph/transforms/repackage.py | 1 + 12 files changed, 101 insertions(+) diff --git a/taskcluster/ci/artifact-build/kind.yml b/taskcluster/ci/artifact-build/kind.yml index 841f02fd10d6..80e038316f1b 100644 --- a/taskcluster/ci/artifact-build/kind.yml +++ b/taskcluster/ci/artifact-build/kind.yml @@ -42,3 +42,5 @@ jobs: tooltool-downloads: public need-xvfb: true keep-artifacts: false + toolchains: + - linux64-node diff --git a/taskcluster/ci/build/android-stuff.yml b/taskcluster/ci/build/android-stuff.yml index 4303bb5b8a54..4a899f9deecd 100644 --- a/taskcluster/ci/build/android-stuff.yml +++ b/taskcluster/ci/build/android-stuff.yml @@ -37,6 +37,7 @@ android-test/opt: toolchains: - android-gradle-dependencies - android-sdk-linux + - linux64-node optimization: skip-unless-changed: - "mobile/android/base/**" @@ -79,6 +80,7 @@ android-test-ccov/opt: toolchains: - android-gradle-dependencies - android-sdk-linux + - linux64-node fetches: fetch: - grcov-linux-x86_64 @@ -125,6 +127,7 @@ android-lint/opt: toolchains: - android-gradle-dependencies - android-sdk-linux + - linux64-node optimization: skip-unless-changed: - "mobile/android/**/*.java" @@ -178,6 +181,7 @@ android-checkstyle/opt: toolchains: - android-gradle-dependencies - android-sdk-linux + - linux64-node optimization: skip-unless-changed: - "mobile/android/**/checkstyle.xml" @@ -227,6 +231,7 @@ android-findbugs/opt: toolchains: - android-gradle-dependencies - android-sdk-linux + - linux64-node optimization: skip-unless-changed: - "mobile/android/**/*.java" @@ -271,6 +276,7 @@ android-geckoview-docs/opt: toolchains: - android-gradle-dependencies - android-sdk-linux + - linux64-node optimization: skip-unless-changed: - "mobile/android/**/*.java" diff --git a/taskcluster/ci/build/android.yml b/taskcluster/ci/build/android.yml index c56a05775338..cdbd769b5f92 100644 --- a/taskcluster/ci/build/android.yml +++ b/taskcluster/ci/build/android.yml @@ -46,6 +46,7 @@ android-api-16/debug: - linux64-rust-android - linux64-rust-size - linux64-sccache + - linux64-node android-x86/opt: description: "Android 4.2 x86 Opt" @@ -95,6 +96,7 @@ android-x86/opt: - linux64-rust-android - linux64-rust-size - linux64-sccache + - linux64-node android-x86-nightly/opt: description: "Android 4.2 x86 Nightly" @@ -150,6 +152,7 @@ android-x86-nightly/opt: - linux64-rust-android - linux64-rust-size - linux64-sccache + - linux64-node android-api-16/opt: description: "Android 4.0 api-16+ Opt" @@ -199,6 +202,7 @@ android-api-16/opt: - linux64-rust-android - linux64-rust-size - linux64-sccache + - linux64-node android-api-16-without-google-play-services/opt: description: "Android 4.0 api-16+ (without Google Play Services) Opt" @@ -247,6 +251,7 @@ android-api-16-without-google-play-services/opt: - linux64-rust-android - linux64-rust-size - linux64-sccache + - linux64-node android-api-16-nightly/opt: description: "Android 4.0 api-16+ Nightly" @@ -302,6 +307,7 @@ android-api-16-nightly/opt: - linux64-rust-android - linux64-rust-size - linux64-sccache + - linux64-node android-aarch64/opt: description: "Android 5.0 AArch64 Opt" @@ -351,6 +357,7 @@ android-aarch64/opt: - linux64-rust-android - linux64-rust-size - linux64-sccache + - linux64-node android-aarch64-nightly/opt: description: "Android 5.0 AArch64 Nightly" @@ -406,3 +413,4 @@ android-aarch64-nightly/opt: - linux64-rust-android - linux64-rust-size - linux64-sccache + - linux64-node diff --git a/taskcluster/ci/build/linux.yml b/taskcluster/ci/build/linux.yml index ea137037c928..5b0af04521a2 100644 --- a/taskcluster/ci/build/linux.yml +++ b/taskcluster/ci/build/linux.yml @@ -27,6 +27,7 @@ linux64/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-plain/opt: description: "Linux64 Opt Plain" @@ -55,6 +56,7 @@ linux64-plain/opt: - linux64-clang - linux64-gcc - linux64-rust + - linux64-node linux64-dmd/opt: description: "Linux64 DMD Opt" @@ -87,6 +89,7 @@ linux64-dmd/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64/pgo: description: "Linux64 PGO" @@ -118,6 +121,7 @@ linux64/pgo: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-fuzzing/debug: description: "Linux64 Fuzzing Debug" @@ -149,6 +153,7 @@ linux64-fuzzing/debug: - linux64-sccache - linux64-rust - linux64-rust-size + - linux64-node linux64/debug: description: "Linux64 Debug" @@ -180,6 +185,7 @@ linux64/debug: - linux64-sccache - linux64-rust - linux64-rust-size + - linux64-node linux64-plain/debug: description: "Linux64 Debug Plain" @@ -208,6 +214,7 @@ linux64-plain/debug: - linux64-clang - linux64-gcc - linux64-rust + - linux64-node linux64-devedition-nightly/opt: description: "Linux64 devedition Nightly" @@ -245,6 +252,7 @@ linux64-devedition-nightly/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-base-toolchains/opt: description: "Linux64 base toolchains Opt" @@ -274,6 +282,7 @@ linux64-base-toolchains/opt: - linux64-gcc-6 - linux64-rust-1.27 - linux64-sccache + - linux64-node linux64-base-toolchains/debug: description: "Linux64 base toolchains Debug" @@ -304,6 +313,7 @@ linux64-base-toolchains/debug: - linux64-gcc-6 - linux64-rust-1.27 - linux64-sccache + - linux64-node linux/opt: description: "Linux32 Opt" @@ -335,6 +345,7 @@ linux/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux/debug: description: "Linux32 Debug" @@ -367,6 +378,7 @@ linux/debug: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux/pgo: description: "Linux32 PGO" @@ -399,6 +411,7 @@ linux/pgo: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux-rusttests/opt: description: "Linux32 Rust tests Opt" @@ -433,6 +446,7 @@ linux-rusttests/opt: - linux64-gcc - linux64-rust - linux64-sccache + - linux64-node linux-rusttests/debug: description: "Linux32 Rust tests Debug" @@ -467,6 +481,7 @@ linux-rusttests/debug: - linux64-gcc - linux64-rust - linux64-sccache + - linux64-node linux-devedition-nightly/opt: description: "Linux32 devedition Nightly" @@ -505,6 +520,7 @@ linux-devedition-nightly/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux-nightly/opt: description: "Linux32 Nightly" @@ -541,6 +557,7 @@ linux-nightly/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-asan/opt: description: "Linux64 Opt ASAN" @@ -572,6 +589,7 @@ linux64-asan/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-asan-fuzzing/opt: description: "Linux64 Fuzzing Opt ASAN" @@ -603,6 +621,7 @@ linux64-asan-fuzzing/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-asan-fuzzing-ccov/opt: description: "Linux64 Fuzzing Opt ASAN w/ Coverage" @@ -635,6 +654,7 @@ linux64-asan-fuzzing-ccov/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-asan-reporter-nightly/opt: description: "Linux64 Opt ASAN Reporter Nightly" @@ -670,6 +690,7 @@ linux64-asan-reporter-nightly/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-asan/debug: description: "Linux64 Debug ASAN" @@ -701,6 +722,7 @@ linux64-asan/debug: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-lto/opt: description: "Linux64 Opt LTO" @@ -733,6 +755,7 @@ linux64-lto/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-lto/debug: description: "Linux64 Debug LTO" @@ -765,6 +788,7 @@ linux64-lto/debug: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-nightly/opt: description: "Linux64 Nightly" @@ -800,6 +824,7 @@ linux64-nightly/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-noopt/debug: description: "Linux64 No-optimize Debug" @@ -832,6 +857,7 @@ linux64-noopt/debug: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node linux64-rusttests/opt: description: "Linux64 Rust tests Opt" @@ -865,6 +891,7 @@ linux64-rusttests/opt: - linux64-gcc - linux64-rust - linux64-sccache + - linux64-node linux64-rusttests/debug: description: "Linux64 Rust tests Debug" @@ -898,6 +925,7 @@ linux64-rusttests/debug: - linux64-gcc - linux64-rust - linux64-sccache + - linux64-node linux64-tup/opt: description: "Linux64 Tup" @@ -930,6 +958,7 @@ linux64-tup/opt: - linux64-rust-nightly - linux64-sccache - linux64-tup + - linux64-node linux64-jsdcov/opt: description: "Linux64-JSDCov Opt" @@ -959,6 +988,7 @@ linux64-jsdcov/opt: - linux64-gcc - linux64-rust - linux64-sccache + - linux64-node linux64-ccov/debug: description: "Linux64-CCov Debug" @@ -989,6 +1019,7 @@ linux64-ccov/debug: - linux64-rust-nightly - linux64-gcc - linux64-sccache + - linux64-node linux64-ccov/opt: description: "Linux64-CCov Opt" @@ -1019,6 +1050,7 @@ linux64-ccov/opt: - linux64-rust - linux64-gcc - linux64-sccache + - linux64-node linux64-add-on-devel/opt: description: "Linux64 add-on-devel" @@ -1050,3 +1082,4 @@ linux64-add-on-devel/opt: - linux64-rust - linux64-rust-size - linux64-sccache + - linux64-node diff --git a/taskcluster/ci/build/macosx.yml b/taskcluster/ci/build/macosx.yml index 8c316176a017..e99006736bc9 100644 --- a/taskcluster/ci/build/macosx.yml +++ b/taskcluster/ci/build/macosx.yml @@ -33,6 +33,7 @@ macosx64/debug: - linux64-rust-macos - linux64-rust-size - linux64-sccache + - linux64-node macosx64/opt: description: "MacOS X x64 Cross-compile" @@ -68,6 +69,7 @@ macosx64/opt: - linux64-rust-macos - linux64-rust-size - linux64-sccache + - linux64-node macosx64-asan-fuzzing/opt: description: "MacOS X x64 Cross-compile Fuzzing ASAN" @@ -102,6 +104,7 @@ macosx64-asan-fuzzing/opt: - linux64-rust-macos - linux64-rust-size - linux64-sccache + - linux64-node macosx64-dmd/opt: description: "MacOS X x64 DMD Cross-compile" @@ -138,6 +141,7 @@ macosx64-dmd/opt: - linux64-rust-macos - linux64-rust-size - linux64-sccache + - linux64-node macosx64-devedition-nightly/opt: description: "MacOS X Dev Edition x64 Nightly" @@ -180,6 +184,7 @@ macosx64-devedition-nightly/opt: - linux64-rust-macos - linux64-rust-size - linux64-sccache + - linux64-node macosx64-noopt/debug: description: "MacOS X x64 No-optimize Debug" @@ -216,6 +221,7 @@ macosx64-noopt/debug: - linux64-rust-macos - linux64-rust-size - linux64-sccache + - linux64-node macosx64-add-on-devel/opt: description: "MacOS X x64 add-on-devel" @@ -251,6 +257,7 @@ macosx64-add-on-devel/opt: - linux64-rust-macos - linux64-rust-size - linux64-sccache + - linux64-node macosx64-nightly/opt: description: "MacOS X x64 Cross-compile Nightly" @@ -326,3 +333,4 @@ macosx64-ccov/debug: - linux64-rust-macos - linux64-rust-size - linux64-sccache + - linux64-node diff --git a/taskcluster/ci/build/windows.yml b/taskcluster/ci/build/windows.yml index 05a341a6ced4..74144d5343ea 100755 --- a/taskcluster/ci/build/windows.yml +++ b/taskcluster/ci/build/windows.yml @@ -28,6 +28,7 @@ win32/debug: - win64-rust - win64-rust-size - win64-sccache + - win64-node win32/opt: description: "Win32 Opt" @@ -65,6 +66,7 @@ win32/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win32-dmd/opt: description: "Win32 DMD Opt" @@ -97,6 +99,7 @@ win32-dmd/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win32/pgo: description: "Win32 Opt PGO" @@ -128,6 +131,7 @@ win32/pgo: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64/debug: description: "Win64 Debug" @@ -159,6 +163,7 @@ win64/debug: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64-plain/debug: description: "Win64 Debug Plain" @@ -188,6 +193,7 @@ win64-plain/debug: toolchains: - win64-clang-cl - win64-rust + - win64-node win64/opt: description: "Win64 Opt" @@ -219,6 +225,7 @@ win64/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64-plain/opt: description: "Win64 Opt Plain" @@ -248,6 +255,7 @@ win64-plain/opt: toolchains: - win64-clang-cl - win64-rust + - win64-node win64-dmd/opt: description: "Win64 DMD Opt" @@ -280,6 +288,7 @@ win64-dmd/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win32-nightly/opt: description: "Win32 Nightly" @@ -324,6 +333,7 @@ win32-nightly/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64-nightly/opt: description: "Win64 Nightly" @@ -361,6 +371,7 @@ win64-nightly/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64/pgo: description: "Win64 Opt PGO" @@ -392,6 +403,7 @@ win64/pgo: - win64-rust - win64-rust-size - win64-sccache + - win64-node win32-add-on-devel/opt: description: "Windows32 add-on-devel" @@ -422,6 +434,7 @@ win32-add-on-devel/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64-add-on-devel/opt: description: "Windows64 add-on-devel" @@ -452,6 +465,7 @@ win64-add-on-devel/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64-noopt/debug: description: "Win64 No-optimize Debug" @@ -482,6 +496,7 @@ win64-noopt/debug: - win64-rust - win64-rust-size - win64-sccache + - win64-node win32-noopt/debug: description: "Win32 No-optimize Debug" @@ -512,6 +527,7 @@ win32-noopt/debug: - win64-rust - win64-rust-size - win64-sccache + - win64-node win32-rusttests/opt: description: "Win32 Opt Rust tests" @@ -542,6 +558,7 @@ win32-rusttests/opt: - win64-clang-cl - win64-rust - win64-sccache + - win64-node win64-rusttests/opt: description: "Win64 Opt Rust tests" @@ -572,6 +589,7 @@ win64-rusttests/opt: - win64-clang-cl - win64-rust - win64-sccache + - win64-node win64-ccov/debug: description: "Win64 Debug Code Coverage" @@ -602,6 +620,7 @@ win64-ccov/debug: - win64-rust-nightly - win64-rust-size - win64-sccache + - win64-node win64-asan/debug: description: "Win64 Debug ASAN" @@ -633,6 +652,7 @@ win64-asan/debug: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64-asan/opt: description: "Win64 Opt ASAN" @@ -664,6 +684,7 @@ win64-asan/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64-asan-reporter-nightly/opt: description: "Win64 Opt ASAN Reporter Nightly" @@ -743,6 +764,7 @@ win32-devedition-nightly/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win64-devedition-nightly/opt: description: "Win64 Dev Edition Nightly" @@ -781,6 +803,7 @@ win64-devedition-nightly/opt: - win64-rust - win64-rust-size - win64-sccache + - win64-node win32-mingw32/opt: description: "Win32 MinGW Opt" @@ -814,6 +837,7 @@ win32-mingw32/opt: - linux64-mingw32-gcc - linux64-mingw32-nsis - linux64-mingw32-fxc2 + - linux64-node win32-msvc/debug: description: "Win32 MSVC Debug" @@ -846,6 +870,7 @@ win32-msvc/debug: - win64-clang-cl - win64-rust - win64-sccache + - win64-node win32-msvc/opt: description: "Win32 MSVC PGO" @@ -884,6 +909,7 @@ win32-msvc/opt: - win64-clang-cl - win64-rust - win64-sccache + - win64-node win64-msvc/debug: description: "Win64 MSVC Debug" @@ -916,6 +942,7 @@ win64-msvc/debug: - win64-clang-cl - win64-rust - win64-sccache + - win64-node win64-msvc/opt: description: "Win64 MSVC PGO" @@ -948,6 +975,7 @@ win64-msvc/opt: - win64-clang-cl - win64-rust - win64-sccache + - win64-node win32-mingw32/debug: description: "Win32 MinGW Debug" @@ -982,3 +1010,4 @@ win32-mingw32/debug: - linux64-mingw32-gcc - linux64-mingw32-nsis - linux64-mingw32-fxc2 + - linux64-node diff --git a/taskcluster/ci/hazard/kind.yml b/taskcluster/ci/hazard/kind.yml index c590e2291695..bc1b5e5de969 100644 --- a/taskcluster/ci/hazard/kind.yml +++ b/taskcluster/ci/hazard/kind.yml @@ -46,6 +46,7 @@ jobs: - linux64-gcc-6 - linux64-gcc-sixgill - linux64-rust + - linux64-node linux64-haz/debug: description: "Browser Hazard Analysis Linux" @@ -66,3 +67,4 @@ jobs: - linux64-gcc-6 - linux64-gcc-sixgill - linux64-rust + - linux64-node diff --git a/taskcluster/ci/static-analysis-autotest/kind.yml b/taskcluster/ci/static-analysis-autotest/kind.yml index c5540dcd9693..5fc90aa21729 100644 --- a/taskcluster/ci/static-analysis-autotest/kind.yml +++ b/taskcluster/ci/static-analysis-autotest/kind.yml @@ -51,6 +51,7 @@ jobs: - linux64-infer - linux64-rust - linux64-sccache + - linux64-node win64-st-autotest/debug: description: "Win64 Debug Static Analysis Autotest" @@ -74,3 +75,4 @@ jobs: - win64-rust - win64-sccache - win64-clang-tidy + - win64-node diff --git a/taskcluster/ci/static-analysis/kind.yml b/taskcluster/ci/static-analysis/kind.yml index 492fa9ed200e..4160cd6c0ea4 100644 --- a/taskcluster/ci/static-analysis/kind.yml +++ b/taskcluster/ci/static-analysis/kind.yml @@ -47,6 +47,7 @@ jobs: - linux64-clang - linux64-rust - linux64-sccache + - linux64-node linux64-st-an/opt: description: "Linux64 Opt Static Analysis" @@ -72,6 +73,7 @@ jobs: - linux64-clang - linux64-rust - linux64-sccache + - linux64-node win32-st-an/debug: description: "Win32 Static Analysis Debug (clang-cl)" @@ -101,6 +103,7 @@ jobs: - win32-clang-cl-st-an - win32-rust - win64-sccache + - win64-node win32-st-an/opt: description: "Win32 Static Analysis Opt (clang-cl)" @@ -130,6 +133,7 @@ jobs: - win32-clang-cl-st-an - win32-rust - win64-sccache + - win64-node win64-st-an/debug: description: "Win64 Static Analysis Debug (clang-cl)" @@ -159,6 +163,7 @@ jobs: - win64-clang-cl-st-an - win64-rust - win64-sccache + - win64-node win64-st-an/opt: description: "Win64 Static Analysis Opt (clang-cl)" @@ -188,3 +193,4 @@ jobs: - win64-clang-cl-st-an - win64-rust - win64-sccache + - win64-node diff --git a/taskcluster/ci/toolchain/macosx.yml b/taskcluster/ci/toolchain/macosx.yml index 43e3c2f04a16..42a190114867 100644 --- a/taskcluster/ci/toolchain/macosx.yml +++ b/taskcluster/ci/toolchain/macosx.yml @@ -34,6 +34,7 @@ macosx64-clang: - linux64-cctools-port - linux64-clang-6 - linux64-gcc-4.9 + - linux64-node macosx64-clang-tidy: description: "Clang-tidy build" @@ -64,6 +65,7 @@ macosx64-clang-tidy: - linux64-cctools-port - linux64-clang-6 - linux64-gcc-4.9 + - linux64-node macosx64-cctools-port: description: "cctools-port toolchain build" @@ -87,6 +89,7 @@ macosx64-cctools-port: toolchains: - linux64-cctools-port - linux64-clang-6 + - linux64-node macosx64-gn: description: "gn toolchain build" diff --git a/taskcluster/ci/valgrind/kind.yml b/taskcluster/ci/valgrind/kind.yml index bf0ddf9a0f97..773ad3d3e3b5 100644 --- a/taskcluster/ci/valgrind/kind.yml +++ b/taskcluster/ci/valgrind/kind.yml @@ -47,3 +47,4 @@ jobs: - linux64-gcc - linux64-rust - linux64-sccache + - linux64-node diff --git a/taskcluster/taskgraph/transforms/repackage.py b/taskcluster/taskgraph/transforms/repackage.py index 13f878320ad9..f3f0b7274c09 100644 --- a/taskcluster/taskgraph/transforms/repackage.py +++ b/taskcluster/taskgraph/transforms/repackage.py @@ -244,6 +244,7 @@ def make_job_description(config, jobs): task['toolchains'] = [ 'linux64-libdmg', 'linux64-hfsplus', + 'linux64-node', ] yield task From 9fc855eec6da87c345645b626d52029ef6d86911 Mon Sep 17 00:00:00 2001 From: Dan Mosedale Date: Fri, 1 Jun 2018 14:59:45 -0700 Subject: [PATCH 41/52] Bug 1478995 - Add node toolchain path to automation mozconfigs, r=gps MozReview-Commit-ID: 37gYPLYJD85 --HG-- extra : rebase_source : a0b1cb598eeb852b7df1912a94a085d31862c86f --- browser/config/mozconfigs/linux32/l10n-mozconfig | 1 + .../mozconfigs/linux32/l10n-mozconfig-devedition | 1 + browser/config/mozconfigs/linux64/hazards | 2 ++ browser/config/mozconfigs/linux64/l10n-mozconfig | 1 + .../mozconfigs/linux64/l10n-mozconfig-devedition | 1 + browser/config/mozconfigs/linux64/plain-opt | 2 ++ browser/config/mozconfigs/macosx64/l10n-mozconfig | 3 +++ .../mozconfigs/macosx64/l10n-mozconfig-devedition | 3 +++ browser/config/mozconfigs/macosx64/repack | 1 + browser/config/mozconfigs/win32/l10n-mozconfig | 3 +++ .../mozconfigs/win32/l10n-mozconfig-devedition | 3 +++ browser/config/mozconfigs/win64/l10n-mozconfig | 3 +++ .../mozconfigs/win64/l10n-mozconfig-devedition | 3 +++ browser/config/mozconfigs/win64/plain-opt | 2 ++ build/mozconfig.common | 1 + build/mozconfig.node | 12 ++++++++++++ .../config/mozconfigs/android-aarch64/l10n-nightly | 2 ++ .../config/mozconfigs/android-api-16/l10n-nightly | 2 ++ .../config/mozconfigs/android-x86/l10n-nightly | 2 ++ 19 files changed, 48 insertions(+) create mode 100644 build/mozconfig.node diff --git a/browser/config/mozconfigs/linux32/l10n-mozconfig b/browser/config/mozconfigs/linux32/l10n-mozconfig index f3691cb53e8d..084af3b12e31 100644 --- a/browser/config/mozconfigs/linux32/l10n-mozconfig +++ b/browser/config/mozconfigs/linux32/l10n-mozconfig @@ -1,6 +1,7 @@ ac_add_options --with-l10n-base=../../l10n ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-branding=browser/branding/nightly +ac_add_options --disable-nodejs . "$topsrcdir/build/mozconfig.no-compile" diff --git a/browser/config/mozconfigs/linux32/l10n-mozconfig-devedition b/browser/config/mozconfigs/linux32/l10n-mozconfig-devedition index 6579fddeb083..46663c628ff0 100644 --- a/browser/config/mozconfigs/linux32/l10n-mozconfig-devedition +++ b/browser/config/mozconfigs/linux32/l10n-mozconfig-devedition @@ -1,6 +1,7 @@ ac_add_options --with-l10n-base=../../l10n ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-branding=browser/branding/aurora +ac_add_options --disable-nodejs . "$topsrcdir/build/mozconfig.no-compile" diff --git a/browser/config/mozconfigs/linux64/hazards b/browser/config/mozconfigs/linux64/hazards index a0bf65882c22..e8907f8d82f3 100644 --- a/browser/config/mozconfigs/linux64/hazards +++ b/browser/config/mozconfigs/linux64/hazards @@ -40,4 +40,6 @@ CFLAGS="$CFLAGS -Wno-attributes" CPPFLAGS="$CPPFLAGS -Wno-attributes" CXXFLAGS="$CXXFLAGS -Wno-attributes" +NODEJS="$TOOLTOOL_DIR/node/bin/node" + . "$topsrcdir/build/mozconfig.common.override" diff --git a/browser/config/mozconfigs/linux64/l10n-mozconfig b/browser/config/mozconfigs/linux64/l10n-mozconfig index f3aa73c749e8..e2598daa2b7e 100644 --- a/browser/config/mozconfigs/linux64/l10n-mozconfig +++ b/browser/config/mozconfigs/linux64/l10n-mozconfig @@ -3,6 +3,7 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-branding=browser/branding/nightly . "$topsrcdir/build/mozconfig.no-compile" +ac_add_options --disable-nodejs export MOZILLA_OFFICIAL=1 diff --git a/browser/config/mozconfigs/linux64/l10n-mozconfig-devedition b/browser/config/mozconfigs/linux64/l10n-mozconfig-devedition index bb6471c4cd94..0c990af376b1 100644 --- a/browser/config/mozconfigs/linux64/l10n-mozconfig-devedition +++ b/browser/config/mozconfigs/linux64/l10n-mozconfig-devedition @@ -3,6 +3,7 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-branding=browser/branding/aurora . "$topsrcdir/build/mozconfig.no-compile" +ac_add_options --disable-nodejs export MOZILLA_OFFICIAL=1 diff --git a/browser/config/mozconfigs/linux64/plain-opt b/browser/config/mozconfigs/linux64/plain-opt index bd5c36a13e6f..c24fe37ccc56 100644 --- a/browser/config/mozconfigs/linux64/plain-opt +++ b/browser/config/mozconfigs/linux64/plain-opt @@ -6,6 +6,8 @@ RUSTC="${TOOLTOOL_DIR}/rustc/bin/rustc" RUSTDOC="${TOOLTOOL_DIR}/rustc/bin/rustdoc" RUSTFMT="${TOOLTOOL_DIR}/rustc/bin/rustfmt" +export NODEJS="${TOOLTOOL_DIR}/node/bin/node" + CC="${TOOLTOOL_DIR}/gcc/bin/gcc" CXX="${TOOLTOOL_DIR}/gcc/bin/g++" diff --git a/browser/config/mozconfigs/macosx64/l10n-mozconfig b/browser/config/mozconfigs/macosx64/l10n-mozconfig index 5d02eb27c612..76ab89799c85 100644 --- a/browser/config/mozconfigs/macosx64/l10n-mozconfig +++ b/browser/config/mozconfigs/macosx64/l10n-mozconfig @@ -13,6 +13,9 @@ ac_add_options --with-l10n-base=../../l10n ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-branding=browser/branding/nightly +ac_add_options --disable-nodejs +unset NODEJS + export MOZILLA_OFFICIAL=1 # Enable Telemetry diff --git a/browser/config/mozconfigs/macosx64/l10n-mozconfig-devedition b/browser/config/mozconfigs/macosx64/l10n-mozconfig-devedition index db7f809b4e2e..6460aa3a355a 100644 --- a/browser/config/mozconfigs/macosx64/l10n-mozconfig-devedition +++ b/browser/config/mozconfigs/macosx64/l10n-mozconfig-devedition @@ -13,6 +13,9 @@ ac_add_options --with-l10n-base=../../l10n ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-branding=browser/branding/aurora +ac_add_options --disable-nodejs +unset NODEJS + if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then ac_add_options --with-macbundlename-prefix=Firefox fi diff --git a/browser/config/mozconfigs/macosx64/repack b/browser/config/mozconfigs/macosx64/repack index 45f98ee71cbc..9974c70bb527 100644 --- a/browser/config/mozconfigs/macosx64/repack +++ b/browser/config/mozconfigs/macosx64/repack @@ -4,4 +4,5 @@ export MKFSHFS=$topsrcdir/hfsplus-tools/newfs_hfs export DMG_TOOL=$topsrcdir/dmg/dmg export HFS_TOOL=$topsrcdir/dmg/hfsplus +export NODEJS=$topsrcdir/node/bin/node ac_add_options --disable-compile-environment diff --git a/browser/config/mozconfigs/win32/l10n-mozconfig b/browser/config/mozconfigs/win32/l10n-mozconfig index da7195985422..9bb6c44a2e50 100644 --- a/browser/config/mozconfigs/win32/l10n-mozconfig +++ b/browser/config/mozconfigs/win32/l10n-mozconfig @@ -5,6 +5,9 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-l10n-base=../../l10n ac_add_options --with-branding=browser/branding/nightly +ac_add_options --disable-nodejs +unset NODEJS + export MOZILLA_OFFICIAL=1 # Enable Telemetry diff --git a/browser/config/mozconfigs/win32/l10n-mozconfig-devedition b/browser/config/mozconfigs/win32/l10n-mozconfig-devedition index e58c13a021b4..7002fb77d43d 100644 --- a/browser/config/mozconfigs/win32/l10n-mozconfig-devedition +++ b/browser/config/mozconfigs/win32/l10n-mozconfig-devedition @@ -5,6 +5,9 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-l10n-base=../../l10n ac_add_options --with-branding=browser/branding/aurora +ac_add_options --disable-nodejs +unset NODEJS + export MOZILLA_OFFICIAL=1 # Enable Telemetry diff --git a/browser/config/mozconfigs/win64/l10n-mozconfig b/browser/config/mozconfigs/win64/l10n-mozconfig index 137b4c3832e6..72570240642d 100644 --- a/browser/config/mozconfigs/win64/l10n-mozconfig +++ b/browser/config/mozconfigs/win64/l10n-mozconfig @@ -6,6 +6,9 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-l10n-base=../../l10n ac_add_options --with-branding=browser/branding/nightly +ac_add_options --disable-nodejs +unset NODEJS + export MOZILLA_OFFICIAL=1 # Enable Telemetry diff --git a/browser/config/mozconfigs/win64/l10n-mozconfig-devedition b/browser/config/mozconfigs/win64/l10n-mozconfig-devedition index 177bc83bc3da..37926495a006 100644 --- a/browser/config/mozconfigs/win64/l10n-mozconfig-devedition +++ b/browser/config/mozconfigs/win64/l10n-mozconfig-devedition @@ -6,6 +6,9 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} ac_add_options --with-l10n-base=../../l10n ac_add_options --with-branding=browser/branding/aurora +ac_add_options --disable-nodejs +unset NODEJS + export MOZILLA_OFFICIAL=1 # Enable Telemetry diff --git a/browser/config/mozconfigs/win64/plain-opt b/browser/config/mozconfigs/win64/plain-opt index bc60ab793906..0632e5c205c9 100644 --- a/browser/config/mozconfigs/win64/plain-opt +++ b/browser/config/mozconfigs/win64/plain-opt @@ -7,6 +7,8 @@ CARGO="${TOOLTOOL_DIR}/rustc/bin/cargo" RUSTDOC="${TOOLTOOL_DIR}/rustc/bin/rustdoc" RUSTFMT="${TOOLTOOL_DIR}/rustc/bin/rustfmt" +NODEJS="${TOOLTOOL_DIR}/node/node.exe" + ac_add_options --target=x86_64-pc-mingw32 ac_add_options --host=x86_64-pc-mingw32 diff --git a/build/mozconfig.common b/build/mozconfig.common index 75364ed791a2..308795ff549c 100644 --- a/build/mozconfig.common +++ b/build/mozconfig.common @@ -19,6 +19,7 @@ MOZ_REQUIRE_SIGNING=${MOZ_REQUIRE_SIGNING-0} ac_add_options --enable-js-shell +. "$topsrcdir/build/mozconfig.node" . "$topsrcdir/build/mozconfig.automation" . "$topsrcdir/build/mozconfig.rust" . "$topsrcdir/build/mozconfig.cache" diff --git a/build/mozconfig.node b/build/mozconfig.node new file mode 100644 index 000000000000..399cf1e1c456 --- /dev/null +++ b/build/mozconfig.node @@ -0,0 +1,12 @@ +# 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/. + +case "$(uname -s)" in +MINGW*) + export NODEJS=$topsrcdir/node/node.exe + ;; +*) + export NODEJS=$topsrcdir/node/bin/node + ;; +esac diff --git a/mobile/android/config/mozconfigs/android-aarch64/l10n-nightly b/mobile/android/config/mozconfigs/android-aarch64/l10n-nightly index 0d2c0b4b7527..fb51f03b8795 100644 --- a/mobile/android/config/mozconfigs/android-aarch64/l10n-nightly +++ b/mobile/android/config/mozconfigs/android-aarch64/l10n-nightly @@ -15,6 +15,8 @@ mk_add_options AUTOCLOBBER= # Global options ac_add_options --disable-tests +ac_add_options --disable-nodejs +unset NODEJS ac_add_options --enable-updater ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} diff --git a/mobile/android/config/mozconfigs/android-api-16/l10n-nightly b/mobile/android/config/mozconfigs/android-api-16/l10n-nightly index bdd0bb41acfa..fdd782f752bd 100644 --- a/mobile/android/config/mozconfigs/android-api-16/l10n-nightly +++ b/mobile/android/config/mozconfigs/android-api-16/l10n-nightly @@ -15,6 +15,8 @@ mk_add_options AUTOCLOBBER= # Global options ac_add_options --disable-tests +ac_add_options --disable-nodejs +unset NODEJS ac_add_options --enable-updater ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} diff --git a/mobile/android/config/mozconfigs/android-x86/l10n-nightly b/mobile/android/config/mozconfigs/android-x86/l10n-nightly index c4cac7ceb010..80fd7b5ed26d 100644 --- a/mobile/android/config/mozconfigs/android-x86/l10n-nightly +++ b/mobile/android/config/mozconfigs/android-x86/l10n-nightly @@ -15,6 +15,8 @@ mk_add_options AUTOCLOBBER= # Global options ac_add_options --disable-tests +ac_add_options --disable-nodejs +unset NODEJS ac_add_options --enable-updater ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} From 6a890f9e340137a1de80ca2e97eedbb32561bd0e Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Wed, 1 Aug 2018 09:40:24 -0700 Subject: [PATCH 42/52] Bug 1473742 - Fix printing fonts loaded with JS API. r=jfkthame Copy over non-rule font faces to the static clone document that is used during printing. MozReview-Commit-ID: 8ggNrCcVpEK --HG-- extra : rebase_source : 27e270edd28c3ecf19a99f4df5398a89e6c53e6a --- dom/base/nsDocument.cpp | 7 +++++ layout/base/tests/chrome/chrome.ini | 2 ++ .../tests/chrome/printpreview_font_api.html | 25 ++++++++++++++++++ .../chrome/printpreview_font_api_ref.html | 23 ++++++++++++++++ .../base/tests/chrome/printpreview_helper.xul | 26 +++++++++++++++++++ layout/style/FontFaceSet.cpp | 11 ++++++++ layout/style/FontFaceSet.h | 2 ++ 7 files changed, 96 insertions(+) create mode 100644 layout/base/tests/chrome/printpreview_font_api.html create mode 100644 layout/base/tests/chrome/printpreview_font_api_ref.html diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index a53d66da4ffe..ddc3b271e69c 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -9578,6 +9578,13 @@ nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer) } } } + + // Font faces created with the JS API will not be reflected in the + // stylesheets and need to be copied over to the cloned document. + if (const FontFaceSet* set = GetFonts()) { + set->CopyNonRuleFacesTo(clonedDoc->Fonts()); + } + } } mCreatingStaticClone = false; diff --git a/layout/base/tests/chrome/chrome.ini b/layout/base/tests/chrome/chrome.ini index a02bfdcead99..278267fc19b7 100644 --- a/layout/base/tests/chrome/chrome.ini +++ b/layout/base/tests/chrome/chrome.ini @@ -13,6 +13,8 @@ support-files = printpreview_bug396024_helper.xul printpreview_bug482976_helper.xul printpreview_helper.xul + printpreview_font_api.html + printpreview_font_api_ref.html file_bug1018265.xul [test_bug396367-1.html] diff --git a/layout/base/tests/chrome/printpreview_font_api.html b/layout/base/tests/chrome/printpreview_font_api.html new file mode 100644 index 000000000000..1f82d5f2d9f9 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_font_api.html @@ -0,0 +1,25 @@ + + + + + + + +

lmnop

+ + + \ No newline at end of file diff --git a/layout/base/tests/chrome/printpreview_font_api_ref.html b/layout/base/tests/chrome/printpreview_font_api_ref.html new file mode 100644 index 000000000000..61b052b4a625 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_font_api_ref.html @@ -0,0 +1,23 @@ + + + + + + + +

lmnop

+ + diff --git a/layout/base/tests/chrome/printpreview_helper.xul b/layout/base/tests/chrome/printpreview_helper.xul index e2ccca2cd314..b9f71204f1c4 100644 --- a/layout/base/tests/chrome/printpreview_helper.xul +++ b/layout/base/tests/chrome/printpreview_helper.xul @@ -280,6 +280,32 @@ function runTest7() { exitprintpreview(); ok(compareCanvases(), "Printing light DOM and shadow DOM should create same output"); + requestAnimationFrame(function() { setTimeout(runTest8); } ); +} + +async function runTest8() { + // Test that fonts loaded with CSS and JS are printed the same. + const iframeElement = document.getElementsByTagName("iframe")[0]; + + // First, snapshot the page with font defined in CSS. + await new Promise((resolve) => { + iframeElement.addEventListener("load", resolve, { capture: true, once: true }); + iframeElement.setAttribute("src", "printpreview_font_api_ref.html"); + }); + printpreview(); + ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)"); + exitprintpreview(); + + // Second, snapshot the page with font loaded in JS. + await new Promise((resolve) => { + iframeElement.addEventListener("message", resolve, { capture: true, once: true }); + iframeElement.setAttribute("src", "printpreview_font_api.html"); + }); + printpreview(); + ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)"); + exitprintpreview(); + ok(compareCanvases(), "Printing pages with fonts loaded from CSS and JS should be the same."); + finish(); } diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp index d0edec1faf21..d812d6978c73 100644 --- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -1936,6 +1936,17 @@ FontFaceSet::RefreshStandardFontLoadPrincipal() } } +void +FontFaceSet::CopyNonRuleFacesTo(FontFaceSet* aFontFaceSet) const +{ + for (const FontFaceRecord& rec : mNonRuleFaces) { + ErrorResult rv; + RefPtr f = rec.mFontFace; + aFontFaceSet->Add(*f, rv); + MOZ_ASSERT(!rv.Failed()); + } +} + // -- FontFaceSet::UserFontSet ------------------------------------------------ /* virtual */ bool diff --git a/layout/style/FontFaceSet.h b/layout/style/FontFaceSet.h index bb5f1c1648b6..3b74aa967c3a 100644 --- a/layout/style/FontFaceSet.h +++ b/layout/style/FontFaceSet.h @@ -177,6 +177,8 @@ public: void RefreshStandardFontLoadPrincipal(); + void CopyNonRuleFacesTo(FontFaceSet* aFontFaceSet) const; + nsIDocument* Document() const { return mDocument; } // -- Web IDL -------------------------------------------------------------- From 170f0fe4dffee141753059c804bbd26edc55b421 Mon Sep 17 00:00:00 2001 From: Dave Townsend Date: Wed, 1 Aug 2018 17:46:24 +0000 Subject: [PATCH 43/52] Bug 1479866: Throw an exception if XUL elements cannot be created. r=bzbarsky Differential Revision: https://phabricator.services.mozilla.com/D2576 --HG-- extra : moz-landing-system : lando --- dom/base/nsDocument.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index ddc3b271e69c..a6de74531215 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -5654,6 +5654,10 @@ nsIDocument::CreateXULElement(const nsAString& aTagName, } RefPtr elem = CreateElem(aTagName, nullptr, kNameSpaceID_XUL, is); + if (!elem) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return nullptr; + } return elem.forget(); } From 533c7f85116315668c4be906abfeae9eecc8154f Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 31 Jul 2018 15:15:57 -0700 Subject: [PATCH 44/52] Bug 1478499 - Do not list pixman.h twice in system-headers.h r=froydnj The file is added both unconditionally and conditionally to no effect. MozReview-Commit-ID: JBZKN2qRf73 --HG-- extra : rebase_source : 74b601ae1d64f8ed7a47b02f79cbef66ac606abc --- config/system-headers.mozbuild | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild index 97dc3f1cde66..7f17843a37bd 100644 --- a/config/system-headers.mozbuild +++ b/config/system-headers.mozbuild @@ -1296,11 +1296,6 @@ if CONFIG['MOZ_ENABLE_CONTENTMANAGER']: 'SelectSingleContentItemPage.h', ] -if not CONFIG['MOZ_TREE_PIXMAN']: - system_headers += [ - 'pixman.h', - ] - if CONFIG['MOZ_SYSTEM_LIBVPX']: system_headers += [ 'vpx_mem/vpx_mem.h', From 280ad8e1df5d68deeab766870481d6484e75f1d9 Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 31 Jul 2018 15:16:04 -0700 Subject: [PATCH 45/52] Bug 1478499 - Skip additional js shell installation via ObjdirFiles in the tup build. r=mshal Having an output to !/js/src/js causes problems for tup, because many compilation invocations will attempt to find headers in !/js/src/js, meaning tup thinks these invocations should depend on generating !/js/src/js (the file). MozReview-Commit-ID: CHP20RqH1OM --HG-- extra : rebase_source : d2fd8ac808a2c9c548eb3962abae5002366d1ea3 --- python/mozbuild/mozbuild/backend/tup.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/python/mozbuild/mozbuild/backend/tup.py b/python/mozbuild/mozbuild/backend/tup.py index 531ffce65e1f..444c8934bae0 100644 --- a/python/mozbuild/mozbuild/backend/tup.py +++ b/python/mozbuild/mozbuild/backend/tup.py @@ -941,9 +941,22 @@ class TupBackend(CommonBackend): if not path: raise Exception("Cannot install to " + target) + js_shell = self.environment.substs.get('JS_SHELL_NAME') + if js_shell: + js_shell = '%s%s' % (js_shell, + self.environment.substs['BIN_SUFFIX']) + for path, files in obj.files.walk(): self._add_features(target, path) for f in files: + + if (js_shell and isinstance(obj, ObjdirFiles) and + f.endswith(js_shell)): + # Skip this convenience install for now. Accessing + # !/js/src/js when trying to find headers creates + # an error for tup when !/js/src/js is also a target. + continue + output_group = None if any(mozpath.match(mozpath.basename(f), p) for p in self._compile_env_files): From 6957b72f3f2840fa47b2b9c03e0d1f67ca98031a Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 31 Jul 2018 15:17:48 -0700 Subject: [PATCH 46/52] Bug 1478499 - Use JS_LIBRARY_NAME rather than LIBRARY_NAME when versioning js symbols. r=mshal MozReview-Commit-ID: HkpddK16VG --HG-- extra : rebase_source : e0e4fe58e6728f151d6f3108fbed984c2245d9b8 --- js/src/build/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/build/Makefile.in b/js/src/build/Makefile.in index ee19104e0ef5..ce91b0c3ca7f 100644 --- a/js/src/build/Makefile.in +++ b/js/src/build/Makefile.in @@ -10,7 +10,7 @@ ifeq (Linux,$(OS_TARGET)) symverscript: symverscript.in $(call py_action,preprocessor, \ - -DVERSION='$(subst -,_,$(LIBRARY_NAME))' $< -o $@) + -DVERSION='$(subst -,_,$(JS_LIBRARY_NAME))' $< -o $@) EXTRA_DEPS += symverscript endif From 493ea8dbbd72a2226be13fe7abe6cbb71f23f9ac Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 31 Jul 2018 15:29:42 -0700 Subject: [PATCH 47/52] Bug 1478499 - Move symbol version script generation for js shared library to moz.build. r=mshal MozReview-Commit-ID: JF3dtk0ybw2 --HG-- extra : rebase_source : b04a5dae91f8a22f5871c9d0cbc38b83171fe90d --- js/src/build/Makefile.in | 11 ----------- js/src/build/moz.build | 16 +++++++++++----- toolkit/library/gen_symverscript.py | 4 ++-- toolkit/library/moz.build | 3 +++ 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/js/src/build/Makefile.in b/js/src/build/Makefile.in index ce91b0c3ca7f..09063a19602f 100644 --- a/js/src/build/Makefile.in +++ b/js/src/build/Makefile.in @@ -4,17 +4,6 @@ # 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/. -# Ensure symbol versions of shared library on Linux do not conflict -# with those in libxul. -ifeq (Linux,$(OS_TARGET)) - -symverscript: symverscript.in - $(call py_action,preprocessor, \ - -DVERSION='$(subst -,_,$(JS_LIBRARY_NAME))' $< -o $@) - -EXTRA_DEPS += symverscript -endif - include $(topsrcdir)/config/rules.mk # check_vanilla_allocations.py is tailored to Linux, so only run it there. diff --git a/js/src/build/moz.build b/js/src/build/moz.build index 65565256ef70..ccfbef6a5dc0 100644 --- a/js/src/build/moz.build +++ b/js/src/build/moz.build @@ -23,6 +23,17 @@ if not CONFIG['JS_STANDALONE']: if CONFIG['JS_SHARED_LIBRARY']: GeckoSharedLibrary('js', linkage=None) SHARED_LIBRARY_NAME = CONFIG['JS_LIBRARY_NAME'] + + # Ensure symbol versions of shared library on Linux do not conflict + # with those in libxul. + if CONFIG['OS_TARGET'] == 'Linux': + GENERATED_FILES += ['symverscript'] + GENERATED_FILES['symverscript'].script = '/toolkit/library/gen_symverscript.py' + GENERATED_FILES['symverscript'].inputs = ['symverscript.in'] + GENERATED_FILES['symverscript'].flags = [ + CONFIG['JS_LIBRARY_NAME'].replace('-', '_'), + ] + LDFLAGS += ['-Wl,-version-script,symverscript'] else: Library('js') @@ -76,11 +87,6 @@ NO_EXPAND_LIBS = True DIST_INSTALL = True -# Ensure symbol versions of shared library on Linux do not conflict -# with those in libxul. -if CONFIG['OS_TARGET'] == 'Linux': - LDFLAGS += ['-Wl,-version-script,symverscript'] - # Run SpiderMonkey style checker after linking the static library. This avoids # running the script for no-op builds. GENERATED_FILES += ['spidermonkey_checks'] diff --git a/toolkit/library/gen_symverscript.py b/toolkit/library/gen_symverscript.py index c8b9ed71798e..90b9291d6c79 100644 --- a/toolkit/library/gen_symverscript.py +++ b/toolkit/library/gen_symverscript.py @@ -8,10 +8,10 @@ import sys import buildconfig from mozbuild.preprocessor import Preprocessor -def main(output, input_file): +def main(output, input_file, version=None): pp = Preprocessor() pp.context.update({ - 'VERSION': 'xul%s' % buildconfig.substs['MOZILLA_SYMBOLVERSION'], + 'VERSION': version, }) pp.out = output pp.do_include(input_file) diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build index 79c21dee12ee..947ea35dbb86 100644 --- a/toolkit/library/moz.build +++ b/toolkit/library/moz.build @@ -345,6 +345,9 @@ if CONFIG['COMPILE_ENVIRONMENT']: GENERATED_FILES += ['symverscript'] GENERATED_FILES['symverscript'].script = 'gen_symverscript.py' GENERATED_FILES['symverscript'].inputs = ['symverscript.in'] + GENERATED_FILES['symverscript'].flags = [ + 'xul%s' % CONFIG['MOZILLA_SYMBOLVERSION'] + ] SYMBOLS_FILE = '!symverscript' # This library is entirely composed of Rust code, and needs to come after From 8f4e7ae4ec9503a00b9e4165736ea0b95fff4c49 Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 31 Jul 2018 16:10:39 -0700 Subject: [PATCH 48/52] Bug 1478499 - Specify the symbol version script for js with SYMBOLS_FILE. r=mshal To make this work correctly we need to start respecting SYMBOLS_FILE under js/src, so we start setting GCC_USE_GNU_LD in js/src/config.status to get this wired up. MozReview-Commit-ID: HYahjev0VUo --HG-- extra : rebase_source : 4bba5fbb1b3689854796ece928219293cfc63d19 --- js/src/build/moz.build | 2 +- js/src/old-configure.in | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/js/src/build/moz.build b/js/src/build/moz.build index ccfbef6a5dc0..7e6c79612671 100644 --- a/js/src/build/moz.build +++ b/js/src/build/moz.build @@ -33,7 +33,7 @@ if CONFIG['JS_SHARED_LIBRARY']: GENERATED_FILES['symverscript'].flags = [ CONFIG['JS_LIBRARY_NAME'].replace('-', '_'), ] - LDFLAGS += ['-Wl,-version-script,symverscript'] + SYMBOLS_FILE = '!symverscript' else: Library('js') diff --git a/js/src/old-configure.in b/js/src/old-configure.in index 09caf0be9950..d4b759913e7b 100644 --- a/js/src/old-configure.in +++ b/js/src/old-configure.in @@ -1819,6 +1819,8 @@ AC_SUBST(HOST_BIN_SUFFIX) AC_SUBST(TARGET_XPCOM_ABI) +AC_SUBST(GCC_USE_GNU_LD) + AC_SUBST(MKSHLIB) AC_SUBST(MKCSHLIB) AC_SUBST_LIST(DSO_CFLAGS) From ed4f391f1c901b84a85fd43e659c810ddebe8d80 Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 31 Jul 2018 16:11:33 -0700 Subject: [PATCH 49/52] Bug 1478499 - Consider GCC_USE_GNU_LD when passing a symbols file in the Tup build for consistency with the Make build. r=mshal MozReview-Commit-ID: 7D4zYj6vhly --HG-- extra : rebase_source : 8552b2f277318c9f56523171f996167066aed6f1 --- python/mozbuild/mozbuild/backend/tup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/mozbuild/mozbuild/backend/tup.py b/python/mozbuild/mozbuild/backend/tup.py index 444c8934bae0..bf1f6c80809d 100644 --- a/python/mozbuild/mozbuild/backend/tup.py +++ b/python/mozbuild/mozbuild/backend/tup.py @@ -379,9 +379,9 @@ class TupBackend(CommonBackend): static_libs += rust_linked symbols_file = [] - if shlib.symbols_file: + if (shlib.symbols_file and + backend_file.environment.substs.get('GCC_USE_GNU_LD')): inputs.append(shlib.symbols_file) - # TODO: Assumes GNU LD symbols_file = ['-Wl,--version-script,%s' % shlib.symbols_file] cmd = ( From b891ceac20c2dab73551eaba68f8a6a0cefa6c08 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Mon, 30 Jul 2018 17:24:16 -0400 Subject: [PATCH 50/52] Bug 1478175 - Implement the branding in the lower left corner of the payment-summary page. r=sfoster MozReview-Commit-ID: Dp8SdEzlrG3 --HG-- extra : rebase_source : d7144c0c83a1574bba6f85d7aae123cf5fdecb24 --- browser/components/payments/res/paymentRequest.css | 13 +++++++++++++ .../components/payments/res/paymentRequest.xhtml | 2 ++ 2 files changed, 15 insertions(+) diff --git a/browser/components/payments/res/paymentRequest.css b/browser/components/payments/res/paymentRequest.css index ebdad85aa7bf..d590c06febb1 100644 --- a/browser/components/payments/res/paymentRequest.css +++ b/browser/components/payments/res/paymentRequest.css @@ -174,3 +174,16 @@ payment-dialog[changes-prevented][complete-status="success"] #pay { bottom: 0; left: 0; } + +#branding { + background-image: url(chrome://branding/content/icon32.png); + background-size: 16px; + background-repeat: no-repeat; + background-position: left center; + padding-inline-start: 20px; + line-height: 20px; +} + +body[dir="rtl"] #branding { + background-position: right center; +} diff --git a/browser/components/payments/res/paymentRequest.xhtml b/browser/components/payments/res/paymentRequest.xhtml index 5a3390e24879..8cf4ba08660b 100644 --- a/browser/components/payments/res/paymentRequest.xhtml +++ b/browser/components/payments/res/paymentRequest.xhtml @@ -66,6 +66,7 @@ + ]> @@ -133,6 +134,7 @@