diff --git a/browser/components/payments/res/containers/address-form.js b/browser/components/payments/res/containers/address-form.js
index e660f8d0ad37..1c18f558871f 100644
--- a/browser/components/payments/res/containers/address-form.js
+++ b/browser/components/payments/res/containers/address-form.js
@@ -95,6 +95,7 @@ export default class AddressForm extends PaymentStateSubscriberMixin(PaymentRequ
// validity will be updated before our handlers get the event
this.form.addEventListener("input", this);
this.form.addEventListener("invalid", this);
+ this.form.addEventListener("change", this);
this.body.appendChild(this.persistCheckbox);
this.body.appendChild(this.genericErrorText);
@@ -210,6 +211,10 @@ export default class AddressForm extends PaymentStateSubscriberMixin(PaymentRequ
handleEvent(event) {
switch (event.type) {
+ case "change": {
+ this.updateSaveButtonState();
+ break;
+ }
case "click": {
this.onClick(event);
break;
diff --git a/browser/components/payments/test/mochitest/test_address_form.html b/browser/components/payments/test/mochitest/test_address_form.html
index d1f09ca45320..062625f64e16 100644
--- a/browser/components/payments/test/mochitest/test_address_form.html
+++ b/browser/components/payments/test/mochitest/test_address_form.html
@@ -141,6 +141,11 @@ add_task(async function test_saveButton() {
is(form.querySelectorAll(":-moz-ui-invalid").length, 0, "Check no fields visibly invalid");
ok(!form.saveButton.disabled, "Save button is enabled after re-filling street-address");
+ fillField(form.form.querySelector("#country"), "CA");
+ ok(form.saveButton.disabled, "Save button is disabled after changing the country to Canada");
+ fillField(form.form.querySelector("#country"), "US");
+ ok(!form.saveButton.disabled, "Save button is enabled after changing the country to US");
+
let messagePromise = promiseContentToChromeMessage("updateAutofillRecord");
is(form.saveButton.textContent, "Add", "Check label");
form.saveButton.scrollIntoView();
diff --git a/browser/components/payments/test/mochitest/test_basic_card_form.html b/browser/components/payments/test/mochitest/test_basic_card_form.html
index 29813393ffe3..10a8cc185f38 100644
--- a/browser/components/payments/test/mochitest/test_basic_card_form.html
+++ b/browser/components/payments/test/mochitest/test_basic_card_form.html
@@ -116,6 +116,17 @@ add_task(async function test_saveButton() {
ok(!form.saveButton.disabled,
"Save button should be enabled since the required fields are filled");
+ fillField(form.form.querySelector("#cc-exp-month"), "");
+ fillField(form.form.querySelector("#cc-exp-year"), "");
+ form.saveButton.focus();
+ ok(form.saveButton.disabled,
+ "Save button should be disabled since the required fields are empty");
+ fillField(form.form.querySelector("#cc-exp-month"), "11");
+ fillField(form.form.querySelector("#cc-exp-year"), year);
+ form.saveButton.focus();
+ ok(!form.saveButton.disabled,
+ "Save button should be enabled since the required fields are filled again");
+
info("blanking the cc-number field");
fillField(form.form.querySelector("#cc-number"), "");
ok(form.saveButton.disabled, "Save button is disabled after blanking cc-number");
@@ -381,6 +392,8 @@ add_task(async function test_field_validity_updates() {
let ccNumber = form.form.querySelector("#cc-number");
let nameInput = form.form.querySelector("#cc-name");
+ let monthInput = form.form.querySelector("#cc-exp-month");
+ let yearInput = form.form.querySelector("#cc-exp-year");
info("test with valid cc-number but missing cc-name");
fillField(ccNumber, "4111111111111111");
@@ -388,10 +401,15 @@ add_task(async function test_field_validity_updates() {
ok(!nameInput.checkValidity(), "cc-name field is invalid when empty");
ok(form.saveButton.disabled, "Save button should be disabled with incomplete input");
- info("correct by adding cc-name value");
+ info("correct by adding cc-name and expiration values");
fillField(nameInput, "First");
+ fillField(monthInput, "11");
+ let year = (new Date()).getFullYear().toString();
+ fillField(yearInput, year);
ok(ccNumber.checkValidity(), "cc-number field is valid with good input");
ok(nameInput.checkValidity(), "cc-name field is valid with a value");
+ ok(monthInput.checkValidity(), "cc-exp-month field is valid with a value");
+ ok(yearInput.checkValidity(), "cc-exp-year field is valid with a value");
ok(!form.saveButton.disabled, "Save button should not be disabled with good input");
info("edit to make the cc-number invalid");
diff --git a/browser/components/preferences/in-content/main.js b/browser/components/preferences/in-content/main.js
index 94438268632a..44d701db5409 100644
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -1553,14 +1553,23 @@ var gMainPane = {
if (this._filter.value)
visibleTypes = visibleTypes.filter(this._matchesFilter, this);
- for (let visibleType of visibleTypes) {
- let item = new HandlerListItem(visibleType);
- item.connectAndAppendToList(this._list);
-
- if (visibleType.type === lastSelectedType) {
- this._list.selectedItem = item.node;
+ let items = visibleTypes.map(visibleType => new HandlerListItem(visibleType));
+ let itemsFragment = document.createDocumentFragment();
+ let lastSelectedItem;
+ for (let item of items) {
+ item.createNode(itemsFragment);
+ if (item.handlerInfoWrapper.type == lastSelectedType) {
+ lastSelectedItem = item;
}
}
+ this._list.appendChild(itemsFragment);
+ for (let item of items) {
+ item.setupNode();
+ }
+
+ if (lastSelectedItem) {
+ this._list.selectedItem = lastSelectedItem.node;
+ }
},
_matchesFilter(aType) {
@@ -2496,11 +2505,13 @@ class HandlerListItem {
}
}
- connectAndAppendToList(list) {
+ createNode(list) {
list.appendChild(document.importNode(gHandlerListItemFragment, true));
this.node = list.lastChild;
gNodeToObjectMap.set(this.node, this);
+ }
+ setupNode() {
this.node.querySelector(".actionsMenu").addEventListener("command",
event => gMainPane.onSelectAction(event.originalTarget));
diff --git a/browser/extensions/formautofill/content/editCreditCard.xhtml b/browser/extensions/formautofill/content/editCreditCard.xhtml
index c804114e188e..d6c3df27fd34 100644
--- a/browser/extensions/formautofill/content/editCreditCard.xhtml
+++ b/browser/extensions/formautofill/content/editCreditCard.xhtml
@@ -28,7 +28,7 @@
-
+
01
02
@@ -46,7 +46,7 @@
-
+
diff --git a/browser/locales/en-US/browser/preferences/connection.ftl b/browser/locales/en-US/browser/preferences/connection.ftl
index e0850a336994..acbc0218b39f 100644
--- a/browser/locales/en-US/browser/preferences/connection.ftl
+++ b/browser/locales/en-US/browser/preferences/connection.ftl
@@ -84,7 +84,7 @@ connection-proxy-socks-remote-dns =
connection-dns-over-https =
.label = Enable DNS over HTTPS
- .accesskey = H
+ .accesskey = b
connection-dns-over-https-url = URL
.accesskey = U
diff --git a/build/macosx/cross-mozconfig.common b/build/macosx/cross-mozconfig.common
index fb4a5ca69855..46d71289fed2 100644
--- a/build/macosx/cross-mozconfig.common
+++ b/build/macosx/cross-mozconfig.common
@@ -32,7 +32,7 @@ export LDFLAGS="-Wl,-syslibroot,$CROSS_SYSROOT -Wl,-dead_strip"
export BINDGEN_CFLAGS="$FLAGS"
export TOOLCHAIN_PREFIX=$CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-
export DSYMUTIL=$topsrcdir/build/macosx/llvm-dsymutil
-mk_add_options "export REAL_DSYMUTIL=$topsrcdir/llvm-dsymutil/bin/llvm-dsymutil"
+mk_add_options "export REAL_DSYMUTIL=$topsrcdir/llvm-dsymutil/bin/dsymutil"
export MKFSHFS=$topsrcdir/hfsplus-tools/newfs_hfs
export DMG_TOOL=$topsrcdir/dmg/dmg
export HFS_TOOL=$topsrcdir/dmg/hfsplus
diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h
index 9a5ba69e3809..e7505a6fe1d9 100644
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3555,14 +3555,16 @@ public:
--mIgnoreOpensDuringUnloadCounter;
}
- void IncrementTrackerCount(bool aIsTrackerBlocked)
+ void IncrementTrackerCount()
{
MOZ_ASSERT(!GetSameTypeParentDocument());
-
++mNumTrackersFound;
- if (aIsTrackerBlocked) {
- ++mNumTrackersBlocked;
- }
+ }
+
+ void IncrementTrackerBlockedCount()
+ {
+ MOZ_ASSERT(!GetSameTypeParentDocument());
+ ++mNumTrackersBlocked;
}
uint32_t NumTrackersFound()
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
index 8f02be32f07d..a3e8e522a93b 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
@@ -363,12 +363,7 @@ public class GeckoView extends FrameLayout {
if (!mSession.isOpen()) {
mSession.open(mRuntime);
}
- // Temporary solution until we find out why mRuntime can end up as null here. It means we
- // might miss an orientation change if we were background OOM-killed, but it's better than
- // crashing. See bug 1484001.
- if (mRuntime != null) {
- mRuntime.orientationChanged();
- }
+ mRuntime.orientationChanged();
super.onAttachedToWindow();
}
@@ -428,11 +423,36 @@ public class GeckoView extends FrameLayout {
final SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
- if (mSession == null && ss.session != null) {
- setSession(ss.session, ss.session.getRuntime());
- } else if (ss.session != null) {
- mSession.transferFrom(ss.session);
- mRuntime = mSession.getRuntime();
+ restoreSession(ss.session);
+ }
+
+ private void restoreSession(final @Nullable GeckoSession savedSession) {
+ if (savedSession == null) {
+ return;
+ }
+
+ GeckoRuntime runtimeToRestore = savedSession.getRuntime();
+ // Note: setSession sets either both mSession and mRuntime, or none of them. So if we don't
+ // have an mRuntime here, we won't have an mSession, either.
+ if (mRuntime == null) {
+ if (runtimeToRestore == null) {
+ // If the saved session is closed, we fall back to using the default runtime, same
+ // as we do when we don't even have an mSession in onAttachedToWindow().
+ runtimeToRestore = GeckoRuntime.getDefault(getContext());
+ }
+ setSession(savedSession, runtimeToRestore);
+ // We already have a session. We only want to transfer the saved session if its close/open
+ // state is the same or better as our current session.
+ } else if (savedSession.isOpen() || !mSession.isOpen()) {
+ if (mSession.isOpen()) {
+ mSession.close();
+ }
+ mSession.transferFrom(savedSession);
+ if (runtimeToRestore != null) {
+ // If the saved session was open, we transfer its runtime as well. Otherwise we just
+ // keep the runtime we already had in mRuntime.
+ mRuntime = runtimeToRestore;
+ }
}
}
diff --git a/netwerk/base/nsChannelClassifier.cpp b/netwerk/base/nsChannelClassifier.cpp
index 2c74c073a703..f6572bb9ae91 100644
--- a/netwerk/base/nsChannelClassifier.cpp
+++ b/netwerk/base/nsChannelClassifier.cpp
@@ -911,8 +911,6 @@ nsChannelClassifier::SetBlockedContent(nsIChannel *channel,
nsCOMPtr doc = docShell->GetDocument();
NS_ENSURE_TRUE(doc, NS_OK);
- doc->IncrementTrackerCount(true);
-
unsigned state;
if (aErrorCode == NS_ERROR_TRACKING_URI) {
state = nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT;
diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp
index e9354b4aafc2..7fde8ced991b 100644
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -331,6 +331,10 @@ HttpBaseChannel::SetIsTrackingResource(bool aIsThirdParty)
MOZ_ASSERT(!mIsThirdPartyTrackingResource);
mIsFirstPartyTrackingResource = true;
}
+
+ if (mLoadInfo) {
+ MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTracker(true));
+ }
}
nsresult
diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
index 7aa3400725d7..b967e4a9a7bd 100644
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -747,10 +747,10 @@ HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
}
bool isTracker;
- if (NS_SUCCEEDED(mLoadInfo->GetIsTracker(&isTracker)) && isTracker) {
+ MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetIsTracker(&isTracker));
+ if (isTracker) {
bool isTrackerBlocked;
- Unused << mLoadInfo->GetIsTrackerBlocked(&isTrackerBlocked);
-
+ MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetIsTrackerBlocked(&isTrackerBlocked));
LOG(("HttpChannelChild::DoOnStartRequest FastBlock %d [this=%p]\n",
isTrackerBlocked,
this));
@@ -758,8 +758,10 @@ HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
nsCOMPtr doc;
if (!NS_WARN_IF(NS_FAILED(GetTopDocument(this,
getter_AddRefs(doc))))) {
-
- doc->IncrementTrackerCount(isTrackerBlocked);
+ doc->IncrementTrackerCount();
+ if (isTrackerBlocked) {
+ doc->IncrementTrackerBlockedCount();
+ }
}
}
diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
index 688053ac3748..3d4c506cdfeb 100644
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -694,6 +694,7 @@ bool
nsHttpChannel::CheckFastBlocked()
{
LOG(("nsHttpChannel::CheckFastBlocked [this=%p]\n", this));
+ MOZ_ASSERT(mIsThirdPartyTrackingResource);
static bool sFastBlockInited = false;
static bool sIsFastBlockEnabled = false;
@@ -706,25 +707,28 @@ nsHttpChannel::CheckFastBlocked()
}
TimeStamp timestamp;
- if (NS_FAILED(GetNavigationStartTimeStamp(×tamp))) {
+ if (NS_FAILED(GetNavigationStartTimeStamp(×tamp)) || !timestamp) {
+ LOG(("FastBlock passed (no timestamp) [this=%p]\n", this));
+
return false;
}
if (!StaticPrefs::browser_contentblocking_enabled() ||
!sIsFastBlockEnabled ||
IsContentPolicyTypeWhitelistedForFastBlock(mLoadInfo) ||
- !timestamp ||
// If the user has interacted with the document, we disable fastblock.
(mLoadInfo && mLoadInfo->GetDocumentHasUserInteracted())) {
+
+ LOG(("FastBlock passed (invalid) [this=%p]\n", this));
+
return false;
}
TimeDuration duration = TimeStamp::NowLoRes() - timestamp;
bool isFastBlocking = duration.ToMilliseconds() >= sFastBlockTimeout;
- if (mLoadInfo) {
- MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTracker(true));
- MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTrackerBlocked(isFastBlocking));
+ if (isFastBlocking && mLoadInfo) {
+ MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTrackerBlocked(true));
}
LOG(("FastBlock %s (%lf) [this=%p]\n",
@@ -6109,6 +6113,10 @@ nsHttpChannel::CancelInternal(nsresult status)
!!mTrackingProtectionCancellationPending;
if (status == NS_ERROR_TRACKING_URI) {
mTrackingProtectionCancellationPending = 0;
+ if (mLoadInfo) {
+ MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTracker(true));
+ MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTrackerBlocked(true));
+ }
}
mCanceled = true;
diff --git a/python/mozbuild/mozbuild/android_version_code.py b/python/mozbuild/mozbuild/android_version_code.py
index 5e786b2358c0..92392d563c42 100644
--- a/python/mozbuild/mozbuild/android_version_code.py
+++ b/python/mozbuild/mozbuild/android_version_code.py
@@ -49,26 +49,24 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
The bits labelled 'x', 'p', and 'g' are feature flags.
- The bit labelled 'x' is 1 if the build is for an x86 or ARM64 architecture,
- and 0 otherwise, which means the build is for a (32-bit) ARM architecture.
+ The bit labelled 'x' is 1 if the build is for an x86 or x86-64 architecture,
+ and 0 otherwise, which means the build is for an ARM or ARM64 architecture.
(Fennec no longer supports ARMv6, so ARM is equivalent to ARMv7.
ARM64 is also known as AArch64; it is logically ARMv8.)
- For the same release, x86 and ARM64 builds have higher version codes and
+ For the same release, x86 and x86_64 builds have higher version codes and
take precedence over ARM builds, so that they are preferred over ARM on
devices that have ARM emulation.
- The bit labelled 'p' is a placeholder that is always 0 (for now).
+ The bit labelled 'p' is 1 if the build is for a 64-bit architecture (x86-64
+ or ARM64), and 0 otherwise, which means the build is for a 32-bit
+ architecture (x86 or ARM). 64-bit builds have higher version codes so
+ they take precedence over 32-bit builds on devices that support 64-bit.
- Firefox no longer supports API 14 or earlier.
-
- This version code computation allows for a split on API levels that allowed
- us to ship builds specifically for Gingerbread (API 9-10); we preserve
- that functionality for sanity's sake, and to allow us to reintroduce a
- split in the future.
-
- At present, the bit labelled 'g' is 1 if the build is an ARM build
- targeting API 16+, which will always be the case.
+ The bit labelled 'g' is 1 if the build targets a recent API level, which
+ is currently always the case, because Firefox no longer ships releases that
+ are split by API levels. However, we may reintroduce a split in the future,
+ in which case the release that targets an older API level will
We throw an explanatory exception when we are within one calendar year of
running out of build events. This gives lots of time to update the version
@@ -113,24 +111,27 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
# for architecture and APK splits.
version |= base << 3
- # None is interpreted as arm.
- if not cpu_arch or cpu_arch == 'armeabi-v7a':
- # 0 is interpreted as SDK 9.
- if not min_sdk or min_sdk == 9:
- pass
- # This used to compare to 11. The 16+ APK directly supersedes 11+, so
- # we reuse this check.
- elif min_sdk == 16:
- version |= 1 << 0
- else:
- raise ValueError("Don't know how to compute android:versionCode "
- "for CPU arch %s and min SDK %s" % (cpu_arch, min_sdk))
- elif cpu_arch in ['x86', 'arm64-v8a']:
+ # 'x' bit is 1 for x86/x86-64 architectures (`None` is interpreted as ARM).
+ if cpu_arch in ['x86', 'x86_64']:
version |= 1 << 2
+ elif not cpu_arch or cpu_arch in ['armeabi-v7a', 'arm64-v8a']:
+ pass
else:
raise ValueError("Don't know how to compute android:versionCode "
"for CPU arch %s" % cpu_arch)
+ # 'p' bit is 1 for 64-bit architectures.
+ if cpu_arch in ['arm64-v8a', 'x86_64']:
+ version |= 1 << 1
+ elif cpu_arch in ['armeabi-v7a', 'x86']:
+ pass
+ else:
+ raise ValueError("Don't know how to compute android:versionCode "
+ "for CPU arch %s" % cpu_arch)
+
+ # 'g' bit is currently always 1, but may depend on `min_sdk` in the future.
+ version |= 1 << 0
+
return version
def android_version_code(buildid, *args, **kwargs):
diff --git a/python/mozlint/mozlint/roller.py b/python/mozlint/mozlint/roller.py
index 779428330393..4dbce089b376 100644
--- a/python/mozlint/mozlint/roller.py
+++ b/python/mozlint/mozlint/roller.py
@@ -178,8 +178,7 @@ class LintRoller(object):
:param outgoing: Lint files touched by commits that are not on the remote repository.
:param workdir: Lint all files touched in the working directory.
:param num_procs: The number of processes to use. Default: cpu count
- :return: A dictionary with file names as the key, and a list of
- :class:`~result.Issue`s as the value.
+ :return: A :class:`~result.ResultSummary` instance.
"""
if not self.linters:
raise LintersNotConfigured
@@ -215,7 +214,7 @@ class LintRoller(object):
if not (paths or vcs_paths) and (workdir or outgoing):
print("warning: no files linted")
- return {}
+ return self.result
# Make sure all paths are absolute. Join `paths` to cwd and `vcs_paths` to root.
paths = set(map(os.path.abspath, paths))
diff --git a/python/mozlint/test/test_roller.py b/python/mozlint/test/test_roller.py
index 71253d452ff7..8a47931beaf5 100644
--- a/python/mozlint/test/test_roller.py
+++ b/python/mozlint/test/test_roller.py
@@ -100,6 +100,18 @@ def test_roll_with_excluded_path(lint, linters, files):
assert result.failed == set([])
+def test_roll_with_no_files_to_lint(lint, linters, capfd):
+ lint.read(linters)
+ lint.mock_vcs([])
+ result = lint.roll([], workdir=True)
+ assert isinstance(result, ResultSummary)
+ assert len(result.issues) == 0
+ assert len(result.failed) == 0
+
+ out, err = capfd.readouterr()
+ assert 'warning: no files linted' in out
+
+
def test_roll_with_invalid_extension(lint, lintdir, filedir):
lint.read(os.path.join(lintdir, 'external.yml'))
result = lint.roll(os.path.join(filedir, 'foobar.py'))
diff --git a/taskcluster/scripts/misc/build-llvm-dsymutil.sh b/taskcluster/scripts/misc/build-llvm-dsymutil.sh
index 406c8a5b7f2e..0c88d4d1fbe2 100755
--- a/taskcluster/scripts/misc/build-llvm-dsymutil.sh
+++ b/taskcluster/scripts/misc/build-llvm-dsymutil.sh
@@ -14,39 +14,7 @@ cd $HOME_DIR/src
git clone -n https://github.com/llvm-mirror/llvm
cd llvm
-git checkout 4727bc748a48e46824eae55a81ae890cd25c3a34
-
-patch -p1 <<'EOF'
-diff --git a/lib/DebugInfo/DWARF/DWARFDie.cpp b/lib/DebugInfo/DWARF/DWARFDie.cpp
-index 17559d2..b08a8d9 100644
---- a/lib/DebugInfo/DWARF/DWARFDie.cpp
-+++ b/lib/DebugInfo/DWARF/DWARFDie.cpp
-@@ -304,20 +304,24 @@ DWARFDie::find(ArrayRef Attrs) const {
-
- Optional
- DWARFDie::findRecursively(ArrayRef Attrs) const {
- if (!isValid())
- return None;
- if (auto Value = find(Attrs))
- return Value;
- if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) {
-+ if (Die.getOffset() == getOffset())
-+ return None;
- if (auto Value = Die.findRecursively(Attrs))
- return Value;
- }
- if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification)) {
-+ if (Die.getOffset() == getOffset())
-+ return None;
- if (auto Value = Die.findRecursively(Attrs))
- return Value;
- }
- return None;
- }
-
- DWARFDie
- DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
-EOF
+git checkout 9df0977d9409b093156ebbd8e1ac99bc32b9eb39
mkdir build
cd build
@@ -60,9 +28,9 @@ cmake \
export LD_LIBRARY_PATH=$HOME_DIR/src/gcc/lib64
-ninja llvm-dsymutil llvm-symbolizer
+ninja dsymutil llvm-symbolizer
-tar --xform='s,^,llvm-dsymutil/,' -Jcf llvm-dsymutil.tar.xz bin/llvm-dsymutil bin/llvm-symbolizer
+tar --xform='s,^,llvm-dsymutil/,' -Jcf llvm-dsymutil.tar.xz bin/dsymutil bin/llvm-symbolizer
mkdir -p $UPLOAD_DIR
cp llvm-dsymutil.tar.xz $UPLOAD_DIR
diff --git a/testing/marionette/driver.js b/testing/marionette/driver.js
index 304acfa9d876..1e6cdfcd9988 100644
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -3143,7 +3143,7 @@ GeckoDriver.prototype.dismissDialog = async function() {
await new Promise(resolve => {
win.addEventListener("DOMModalDialogClosed", whenIdle(win, () => {
- this.dialog = modal.findModalDialogs(this.curBrowser);
+ this.dialog = null;
resolve();
}), {once: true});
@@ -3162,7 +3162,7 @@ GeckoDriver.prototype.acceptDialog = async function() {
await new Promise(resolve => {
win.addEventListener("DOMModalDialogClosed", whenIdle(win, () => {
- this.dialog = modal.findModalDialogs(this.curBrowser);
+ this.dialog = null;
resolve();
}), {once: true});
diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py
index 4c71384185bd..429fb16e69fe 100644
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py
@@ -1,3 +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/.
+
from __future__ import absolute_import
from marionette_driver.by import By
@@ -6,7 +10,7 @@ from marionette_driver import errors
from marionette_driver.marionette import Alert
from marionette_driver.wait import Wait
-from marionette_harness import MarionetteTestCase, parameterized, WindowManagerMixin
+from marionette_harness import MarionetteTestCase, WindowManagerMixin
class BaseAlertTestCase(WindowManagerMixin, MarionetteTestCase):
@@ -23,6 +27,10 @@ class BaseAlertTestCase(WindowManagerMixin, MarionetteTestCase):
Wait(self.marionette, timeout=timeout).until(
lambda _: self.alert_present)
+ def wait_for_alert_closed(self, timeout=None):
+ Wait(self.marionette, timeout=timeout).until(
+ lambda _: not self.alert_present)
+
class TestTabModalAlerts(BaseAlertTestCase):
@@ -35,12 +43,13 @@ class TestTabModalAlerts(BaseAlertTestCase):
self.marionette.navigate(self.test_page)
def tearDown(self):
- # Ensure to close all possible remaining tab modal dialogs
+ # Ensure to close a possible remaining tab modal dialog
try:
- while True:
- alert = self.marionette.switch_to_alert()
- alert.dismiss()
- except errors.NoAlertPresentException:
+ alert = self.marionette.switch_to_alert()
+ alert.dismiss()
+
+ self.wait_for_alert_closed()
+ except:
pass
super(TestTabModalAlerts, self).tearDown()
@@ -51,6 +60,50 @@ class TestTabModalAlerts(BaseAlertTestCase):
with self.assertRaises(errors.NoAlertPresentException):
Alert(self.marionette).dismiss()
+ def test_alert_accept(self):
+ self.marionette.find_element(By.ID, "tab-modal-alert").click()
+ self.wait_for_alert()
+ alert = self.marionette.switch_to_alert()
+ alert.accept()
+
+ def test_alert_dismiss(self):
+ self.marionette.find_element(By.ID, "tab-modal-alert").click()
+ self.wait_for_alert()
+ alert = self.marionette.switch_to_alert()
+ alert.dismiss()
+
+ def test_confirm_accept(self):
+ self.marionette.find_element(By.ID, "tab-modal-confirm").click()
+ self.wait_for_alert()
+ alert = self.marionette.switch_to_alert()
+ alert.accept()
+ self.wait_for_condition(
+ lambda mn: mn.find_element(By.ID, "confirm-result").text == "true")
+
+ def test_confirm_dismiss(self):
+ self.marionette.find_element(By.ID, "tab-modal-confirm").click()
+ self.wait_for_alert()
+ alert = self.marionette.switch_to_alert()
+ alert.dismiss()
+ self.wait_for_condition(
+ lambda mn: mn.find_element(By.ID, "confirm-result").text == "false")
+
+ def test_prompt_accept(self):
+ self.marionette.find_element(By.ID, "tab-modal-prompt").click()
+ self.wait_for_alert()
+ alert = self.marionette.switch_to_alert()
+ alert.accept()
+ self.wait_for_condition(
+ lambda mn: mn.find_element(By.ID, "prompt-result").text == "")
+
+ def test_prompt_dismiss(self):
+ self.marionette.find_element(By.ID, "tab-modal-prompt").click()
+ self.wait_for_alert()
+ alert = self.marionette.switch_to_alert()
+ alert.dismiss()
+ self.wait_for_condition(
+ lambda mn: mn.find_element(By.ID, "prompt-result").text == "null")
+
def test_alert_opened_before_session_starts(self):
self.marionette.find_element(By.ID, "tab-modal-alert").click()
self.wait_for_alert()
@@ -62,45 +115,40 @@ class TestTabModalAlerts(BaseAlertTestCase):
alert = self.marionette.switch_to_alert()
alert.dismiss()
- @parameterized("alert", "alert", "undefined")
- @parameterized("confirm", "confirm", "true")
- @parameterized("prompt", "prompt", "")
- def test_accept(self, value, result):
- self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
- self.wait_for_alert()
- alert = self.marionette.switch_to_alert()
- alert.accept()
- self.assertEqual(self.marionette.find_element(By.ID, "text").text, result)
-
- @parameterized("alert", "alert", "undefined")
- @parameterized("confirm", "confirm", "false")
- @parameterized("prompt", "prompt", "null")
- def test_dismiss(self, value, result):
- self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
- self.wait_for_alert()
- alert = self.marionette.switch_to_alert()
- alert.dismiss()
- self.assertEqual(self.marionette.find_element(By.ID, "text").text, result)
-
- @parameterized("alert", "alert", "Marionette alert")
- @parameterized("confirm", "confirm", "Marionette confirm")
- @parameterized("prompt", "prompt", "Marionette prompt")
- def test_text(self, value, text):
+ def test_alert_text(self):
with self.assertRaises(errors.NoAlertPresentException):
alert = self.marionette.switch_to_alert()
alert.text
- self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
+ self.marionette.find_element(By.ID, "tab-modal-alert").click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
- self.assertEqual(alert.text, text)
+ self.assertEqual(alert.text, "Marionette alert")
alert.accept()
- @parameterized("alert", "alert")
- @parameterized("confirm", "confirm")
- def test_set_text_throws(self, value):
+ def test_prompt_text(self):
+ with self.assertRaises(errors.NoAlertPresentException):
+ alert = self.marionette.switch_to_alert()
+ alert.text
+ self.marionette.find_element(By.ID, "tab-modal-prompt").click()
+ self.wait_for_alert()
+ alert = self.marionette.switch_to_alert()
+ self.assertEqual(alert.text, "Marionette prompt")
+ alert.accept()
+
+ def test_confirm_text(self):
+ with self.assertRaises(errors.NoAlertPresentException):
+ alert = self.marionette.switch_to_alert()
+ alert.text
+ self.marionette.find_element(By.ID, "tab-modal-confirm").click()
+ self.wait_for_alert()
+ alert = self.marionette.switch_to_alert()
+ self.assertEqual(alert.text, "Marionette confirm")
+ alert.accept()
+
+ def test_set_text_throws(self):
with self.assertRaises(errors.NoAlertPresentException):
Alert(self.marionette).send_keys("Foo")
- self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
+ self.marionette.find_element(By.ID, "tab-modal-alert").click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
with self.assertRaises(errors.ElementNotInteractableException):
@@ -111,9 +159,10 @@ class TestTabModalAlerts(BaseAlertTestCase):
self.marionette.find_element(By.ID, "tab-modal-prompt").click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
- alert.send_keys("Foo bar")
+ alert.send_keys("Some text!")
alert.accept()
- self.assertEqual(self.marionette.find_element(By.ID, "text").text, "Foo bar")
+ self.wait_for_condition(
+ lambda mn: mn.find_element(By.ID, "prompt-result").text == "Some text!")
def test_set_text_dismiss(self):
self.marionette.find_element(By.ID, "tab-modal-prompt").click()
@@ -121,51 +170,35 @@ class TestTabModalAlerts(BaseAlertTestCase):
alert = self.marionette.switch_to_alert()
alert.send_keys("Some text!")
alert.dismiss()
- self.assertEqual(self.marionette.find_element(By.ID, "text").text, "null")
+ self.wait_for_condition(
+ lambda mn: mn.find_element(By.ID, "prompt-result").text == "null")
def test_unrelated_command_when_alert_present(self):
self.marionette.find_element(By.ID, "tab-modal-alert").click()
self.wait_for_alert()
with self.assertRaises(errors.UnexpectedAlertOpen):
- self.marionette.find_element(By.ID, "text")
+ self.marionette.find_element(By.ID, "click-result")
def test_modal_is_dismissed_after_unexpected_alert(self):
self.marionette.find_element(By.ID, "tab-modal-alert").click()
self.wait_for_alert()
with self.assertRaises(errors.UnexpectedAlertOpen):
- self.marionette.find_element(By.ID, "text")
+ self.marionette.find_element(By.ID, "click-result")
assert not self.alert_present
- def test_handle_two_modal_dialogs(self):
- self.marionette.find_element(By.ID, "open-two-dialogs").click()
-
- self.wait_for_alert()
- alert1 = self.marionette.switch_to_alert()
- alert1.send_keys("foo")
- alert1.accept()
-
- alert2 = self.marionette.switch_to_alert()
- alert2.send_keys("bar")
- alert2.accept()
-
- self.assertEqual(self.marionette.find_element(By.ID, "text1").text, "foo")
- self.assertEqual(self.marionette.find_element(By.ID, "text2").text, "bar")
-
class TestModalAlerts(BaseAlertTestCase):
def setUp(self):
super(TestModalAlerts, self).setUp()
- self.marionette.set_pref(
- "network.auth.non-web-content-triggered-resources-http-auth-allow",
- True)
+ self.marionette.set_pref("network.auth.non-web-content-triggered-resources-http-auth-allow",
+ True)
def tearDown(self):
# Ensure to close a possible remaining modal dialog
self.close_all_windows()
- self.marionette.clear_pref(
- "network.auth.non-web-content-triggered-resources-http-auth-allow")
+ self.marionette.clear_pref("network.auth.non-web-content-triggered-resources-http-auth-allow")
super(TestModalAlerts, self).tearDown()
@@ -176,6 +209,8 @@ class TestModalAlerts(BaseAlertTestCase):
alert = self.marionette.switch_to_alert()
alert.dismiss()
+ self.wait_for_alert_closed()
+
status = Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
element_present(By.ID, "status")
)
@@ -191,3 +226,5 @@ class TestModalAlerts(BaseAlertTestCase):
alert = self.marionette.switch_to_alert()
alert.dismiss()
+
+ self.wait_for_alert_closed()
diff --git a/testing/marionette/harness/marionette_harness/www/test_tab_modal_dialogs.html b/testing/marionette/harness/marionette_harness/www/test_tab_modal_dialogs.html
index 155a36d70f17..e31364ec20df 100644
--- a/testing/marionette/harness/marionette_harness/www/test_tab_modal_dialogs.html
+++ b/testing/marionette/harness/marionette_harness/www/test_tab_modal_dialogs.html
@@ -7,37 +7,28 @@
Dialog Test
- Open an alert dialog.
- Open a confirm dialog.
- Open a prompt dialog.
- Open two prompts.
- Make text appear.
-
-
-
-
+ Open an alert dialog.
+ Open a confirm dialog.
+ Open a prompt dialog.
+ Make text appear.
+
+
+