Merge mozilla-central to mozilla-inbound. on a CLOSED TREE

This commit is contained in:
Andreea Pavel 2019-04-19 00:50:26 +03:00
commit 1d5a79ec29
763 changed files with 10379 additions and 3867 deletions

View File

@ -1277,6 +1277,18 @@ void Accessible::ApplyARIAState(uint64_t* aState) const {
break;
}
}
} else {
// Sometimes, we use aria-activedescendant targeting something which isn't
// actually a descendant. This is technically a spec violation, but it's a
// useful hack which makes certain things much easier. For example, we use
// this for "fake focus" for multi select browser tabs and Quantumbar
// autocomplete suggestions.
// In these cases, the aria-activedescendant code above won't make the
// active item focusable. It doesn't make sense for something to have
// focus when it isn't focusable, so fix that here.
if (FocusMgr()->IsActiveItem(this)) {
*aState |= states::FOCUSABLE;
}
}
// special case: A native button element whose role got transformed by ARIA to

View File

@ -1062,9 +1062,6 @@ void DocAccessible::ContentStateChanged(dom::Document* aDocument,
}
}
void DocAccessible::DocumentStatesChanged(dom::Document* aDocument,
EventStates aStateMask) {}
void DocAccessible::CharacterDataWillChange(nsIContent* aContent,
const CharacterDataChangeInfo&) {}
@ -2093,8 +2090,11 @@ bool DocAccessible::MoveChild(Accessible* aChild, Accessible* aNewParent,
int32_t aIdxInParent) {
MOZ_ASSERT(aChild, "No child");
MOZ_ASSERT(aChild->Parent(), "No parent");
MOZ_ASSERT(aIdxInParent <= static_cast<int32_t>(aNewParent->ChildCount()),
"Wrong insertion point for a moving child");
// We can't guarantee MoveChild works correctly for accessibilities storing
// children outside mChildren.
MOZ_ASSERT(
aIdxInParent <= static_cast<int32_t>(aNewParent->mChildren.Length()),
"Wrong insertion point for a moving child");
Accessible* curParent = aChild->Parent();
@ -2132,14 +2132,11 @@ bool DocAccessible::MoveChild(Accessible* aChild, Accessible* aNewParent,
return true;
}
MOZ_ASSERT(aIdxInParent <= static_cast<int32_t>(aNewParent->ChildCount()),
"Wrong insertion point for a moving child");
// If the child cannot be re-inserted into the tree, then make sure to remove
// it from its present parent and then shutdown it.
bool hasInsertionPoint =
(aIdxInParent != -1) ||
(aIdxInParent <= static_cast<int32_t>(aNewParent->ChildCount()));
(aIdxInParent >= 0) &&
(aIdxInParent <= static_cast<int32_t>(aNewParent->mChildren.Length()));
TreeMutation rmut(curParent);
rmut.BeforeRemoval(aChild, hasInsertionPoint && TreeMutation::kNoShutdown);
@ -2180,7 +2177,7 @@ void DocAccessible::CacheChildrenInSubtree(Accessible* aRoot,
TreeWalker walker(root);
while (Accessible* child = walker.Next()) {
if (child->IsBoundToParent()) {
MoveChild(child, root, root->ChildCount());
MoveChild(child, root, root->mChildren.Length());
continue;
}

View File

@ -145,6 +145,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429547
gQueue.push(new changeARIAActiveDescendantInvalid("listbox", "roaming3"));
gQueue.push(new moveARIAActiveDescendantID("roaming", "roaming3"));
gQueue.push(new synthFocus("activedesc_nondesc_input",
new focusChecker("activedesc_nondesc_option")));
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -185,5 +188,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429547
<li role="option" id="combobox_option2">option2</li>
</ul>
</div>
<!-- aria-activedescendant targeting a non-descendant -->
<input id="activedesc_nondesc_input" aria-activedescendant="activedesc_nondesc_option">
<div role="listbox">
<div role="option" id="activedesc_nondesc_option">option</div>
</div>
</body>
</html>

View File

@ -173,9 +173,6 @@ var whitelist = [
{file: "chrome://devtools/skin/images/aboutdebugging-firefox-release.svg",
isFromDevTools: true},
{file: "chrome://devtools/skin/images/next.svg", isFromDevTools: true},
// kvstore.jsm wraps the API in nsIKeyValue.idl in a more ergonomic API
// It landed in bug 1490496, and we expect to start using it shortly.
{file: "resource://gre/modules/kvstore.jsm"},
// Bug 1526672
{file: "resource://app/localization/en-US/browser/touchbar/touchbar.ftl",
platforms: ["linux", "win"]},

View File

@ -0,0 +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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="context-fill" d="M28,4l-2,2v4h-4V6l-2-2l-2,2v4h-4V6l-2-2l-2,2v4H6V6L4,4L2,6v22h4v-4h4v4h4v-4h4v4h4v-4h4v4h4V6L28,4z M6,22V12 h4v10H6z M14,22V12h4v10H14z M22,22V12h4v10H22z"/>
</svg>

After

Width:  |  Height:  |  Size: 497 B

View File

@ -38,6 +38,15 @@
--identity-icon-color: #af51f5;
}
.identity-color-toolbar {
--identity-tab-color: var(--lwt-toolbar-field-color, -moz-FieldText);
--identity-icon-color: var(--lwt-toolbar-field-color, -moz-FieldText);
}
.identity-icon-fence {
--identity-icon: url("resource://usercontext-content/fence.svg");
}
.identity-icon-fingerprint {
--identity-icon: url("resource://usercontext-content/fingerprint.svg");
}

View File

@ -10,6 +10,7 @@ browser.jar:
content/cart.svg (content/cart.svg)
content/circle.svg (content/circle.svg)
content/dollar.svg (content/dollar.svg)
content/fence.svg (content/fence.svg)
content/fingerprint.svg (content/fingerprint.svg)
content/gift.svg (content/gift.svg)
content/vacation.svg (content/vacation.svg)

View File

@ -4,7 +4,6 @@
<title>WebExtension test</title>
<meta charset="utf-8">
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
</head>

View File

@ -8,7 +8,6 @@ Test that editCreditCard.xhtml is accessible for tests in the parent directory.
<title>Test that editCreditCard.xhtml is accessible</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>

View File

@ -7,7 +7,6 @@ Test the ObservedPropertiesMixin
<meta charset="utf-8">
<title>Test the ObservedPropertiesMixin</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="payments_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>

View File

@ -7,7 +7,6 @@ Test the PaymentStateSubscriberMixin
<meta charset="utf-8">
<title>Test the PaymentStateSubscriberMixin</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="sinon-7.2.7.js"></script>
<script src="payments_common.js"></script>

View File

@ -8,7 +8,6 @@ Test the PaymentsStore
<title>Test the PaymentsStore</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="sinon-7.2.7.js"></script>
<script src="payments_common.js"></script>

View File

@ -8,7 +8,6 @@ Test the accepted-cards element
<title>Test the accepted-cards element</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="sinon-7.2.7.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -8,7 +8,6 @@ Test the address-form element
<title>Test the address-form element</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="sinon-7.2.7.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the address-option component
<meta charset="utf-8">
<title>Test the address-option component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the address-picker component
<meta charset="utf-8">
<title>Test the address-picker component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -8,7 +8,6 @@ Test the basic-card-form element
<title>Test the basic-card-form element</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="sinon-7.2.7.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the basic-card-option component
<meta charset="utf-8">
<title>Test the basic-card-option component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the address-picker component
<meta charset="utf-8">
<title>Test the billing-address-picker component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the completion-error-page component
<meta charset="utf-8">
<title>Test the completion-error-page component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the currency-amount component
<meta charset="utf-8">
<title>Test the currency-amount component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="payments_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>

View File

@ -7,7 +7,6 @@ Test the labelled-checkbox component
<meta charset="utf-8">
<title>Test the labelled-checkbox component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="payments_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>

View File

@ -7,7 +7,6 @@
<meta charset="utf-8">
<title>Test the order-details component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the paymentOptions address-picker
<meta charset="utf-8">
<title>Test the paymentOptions address-picker</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the payment-details-item component
<meta charset="utf-8">
<title>Test the payment-details-item component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="payments_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>

View File

@ -7,7 +7,6 @@ Test the payment-dialog custom element
<meta charset="utf-8">
<title>Test the payment-dialog element</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="sinon-7.2.7.js"></script>
<script src="payments_common.js"></script>

View File

@ -7,7 +7,6 @@ Test the payment-dialog custom element
<meta charset="utf-8">
<title>Test the payment-dialog element</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the payment-method-picker component
<meta charset="utf-8">
<title>Test the payment-method-picker component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the rich-select component
<meta charset="utf-8">
<title>Test the rich-select component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="payments_common.js"></script>
<script src="../../res/unprivileged-fallbacks.js"></script>

View File

@ -7,7 +7,6 @@ Test the shipping-option-picker component
<meta charset="utf-8">
<title>Test the shipping-option-picker component</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="payments_common.js"></script>

View File

@ -35,6 +35,7 @@ let gContainersManager = {
"pet",
"tree",
"chill",
"fence",
],
colors: [
@ -46,6 +47,7 @@ let gContainersManager = {
"red",
"pink",
"purple",
"toolbar",
],
onLoad() {

View File

@ -150,15 +150,15 @@
</hbox>
<hbox class="extra-information-label all-third-party-cookies-option" hidden="true">
<image class="content-blocking-cookies-image"/>
<label data-l10n-id="content-blocking-third-party-cookies"/>
<label data-l10n-id="content-blocking-all-third-party-cookies"/>
</hbox>
<hbox class="extra-information-label all-cookies-option" hidden="true">
<image class="content-blocking-cookies-image"/>
<label data-l10n-id="content-blocking-third-party-cookies"/>
<label data-l10n-id="content-blocking-all-cookies"/>
</hbox>
<hbox class="extra-information-label unvisited-cookies-option" hidden="true">
<image class="content-blocking-cookies-image"/>
<label data-l10n-id="content-blocking-third-party-cookies"/>
<label data-l10n-id="content-blocking-unvisited-cookies"/>
</hbox>
<hbox class="extra-information-label third-party-tracking-cookies-option" hidden="true">
<image class="content-blocking-cookies-image"/>

View File

@ -1,7 +1,6 @@
<!DOCTYPE html>
<meta charset="utf8">
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script>
/* global SimpleTest SpecialPowers add_task */

View File

@ -8,7 +8,6 @@ https://trac.torproject.org/projects/tor/ticket/1517
<meta charset="utf-8">
<title>Test for Tor Bug 1517 and Mozilla Bug 1424341</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>

View File

@ -206,11 +206,7 @@ this.TranslationDocument.prototype = {
// Let the event loop breath on every 100 nodes
// that are replaced.
const YIELD_INTERVAL = 100;
let maybeYield = Async.jankYielder(YIELD_INTERVAL);
for (let root of this.roots) {
root.swapText(target);
await maybeYield();
}
await Async.yieldingForEach(this.roots, root => root.swapText(target), YIELD_INTERVAL);
})();
},
};

View File

@ -92,6 +92,7 @@ class UrlbarInput {
this.lastQueryContextPromise = Promise.resolve();
this._actionOverrideKeyCount = 0;
this._autofillPlaceholder = "";
this._deletedEndOfAutofillPlaceholder = false;
this._lastSearchString = "";
this._resultForCurrentValue = null;
this._suppressStartQuery = false;
@ -182,6 +183,8 @@ class UrlbarInput {
}
this.removeEventListener("mousedown", this);
this.editor.removeEditActionListener(this);
this.view.panel.remove();
this.inputField.controllers.removeControllerAt(0);
@ -561,8 +564,6 @@ class UrlbarInput {
*
* @param {boolean} [options.allowAutofill]
* Whether or not to allow providers to include autofill results.
* @param {number} [options.lastKey]
* The last key the user entered (as a key code).
* @param {string} [options.searchString]
* The search string. If not given, the current input value is used.
* Otherwise, the current input value must start with this value.
@ -580,7 +581,6 @@ class UrlbarInput {
*/
startQuery({
allowAutofill = true,
lastKey = null,
searchString = null,
resetSearchState = true,
allowEmptyInput = true,
@ -610,7 +610,6 @@ class UrlbarInput {
this.lastQueryContextPromise = this.controller.startQuery(new UrlbarQueryContext({
allowAutofill,
isPrivate: this.isPrivate,
lastKey,
maxResults: UrlbarPrefs.get("maxRichResults"),
muxer: "UnifiedComplete",
providers: ["UnifiedComplete"],
@ -668,6 +667,31 @@ class UrlbarInput {
this.textbox.classList.remove("hidden-focus");
}
/**
* nsIEditActionListener method implementation. We use this to detect when
* the user deletes autofilled substrings.
*
* There is also a DidDeleteSelection method, but it's called before the input
* event is fired. So the order is: WillDeleteSelection, DidDeleteSelection,
* input event. Further, in DidDeleteSelection, the passed-in selection
* object is the same as the object passed to WillDeleteSelection, but by that
* point its properties have been adjusted to account for the deletion. For
* example, the endOffset property of its range will be smaller than it was in
* WillDeleteSelection. Therefore we compute whether the user deleted the
* autofilled substring here in WillDeleteSelection instead of deferring it to
* when we handle the input event.
*
* @param {Selection} selection
* The Selection object.
*/
WillDeleteSelection(selection) {
this._deletedEndOfAutofillPlaceholder =
selection &&
selection.getRangeAt(0).endOffset ==
this._autofillPlaceholder.length &&
this._autofillPlaceholder.endsWith(String(selection));
}
// Getters and Setters below.
get focused() {
@ -1273,6 +1297,9 @@ class UrlbarInput {
this._untrimmedValue = value;
this.window.gBrowser.userTypedValue = value;
let deletedEndOfAutofillPlaceholder = this._deletedEndOfAutofillPlaceholder;
this._deletedEndOfAutofillPlaceholder = false;
let compositionState = this._compositionState;
let compositionClosedPopup = this._compositionClosedPopup;
@ -1311,13 +1338,8 @@ class UrlbarInput {
}
let sameSearchStrings = value == this._lastSearchString;
// TODO (bug 1524550): Properly detect autofill removal, rather than
// guessing based on string prefixes.
let deletedAutofilledSubstring =
sameSearchStrings &&
value.length < this._autofillPlaceholder.length &&
this._autofillPlaceholder.startsWith(value);
deletedEndOfAutofillPlaceholder && sameSearchStrings;
// Don't search again when the new search would produce the same results.
// If we're handling a composition input, we must continue the search
@ -1332,21 +1354,26 @@ class UrlbarInput {
let allowAutofill =
this._maybeAutofillOnInput(value, deletedAutofilledSubstring);
// TODO Bug 1524550: Fill in lastKey, and add anything else we need.
this.startQuery({
searchString: value,
allowAutofill,
lastKey: null,
resetSearchState: false,
});
}
_on_select(event) {
if (!Services.clipboard.supportsSelectionClipboard()) {
if (!this.window.windowUtils.isHandlingUserInput) {
// Register the editor listener we use to detect when the user deletes
// autofilled substrings. The editor is destroyed and removes all its
// listeners at various surprising times, and autofill causes a non-user
// select, which is why we do this here instead of, for example, in the
// constructor. addEditActionListener is idempotent, so it's OK to call
// it even when we're already registered.
this.editor.addEditActionListener(this);
return;
}
if (!this.window.windowUtils.isHandlingUserInput) {
if (!Services.clipboard.supportsSelectionClipboard()) {
return;
}

View File

@ -394,9 +394,6 @@ class UrlbarQueryContext {
* @param {string} options.searchString
* The string the user entered in autocomplete. Could be the empty string
* in the case of the user opening the popup via the mouse.
* @param {number} options.lastKey
* The last key the user entered (as a key code). Could be null if the search
* was started via the mouse.
* @param {boolean} options.isPrivate
* Set to true if this query was started from a private browsing window.
* @param {number} options.maxResults
@ -410,7 +407,6 @@ class UrlbarQueryContext {
this._checkRequiredOptions(options, [
"allowAutofill",
"isPrivate",
"lastKey",
"maxResults",
"searchString",
]);

View File

@ -353,7 +353,6 @@ class UrlbarView {
// icon if it's not too far from the edge of the window. We define
// "too far" as "more than 30% of the window's width AND more than
// 250px".
let contentWidth = width;
let boundToCheck = this.window.RTL_UI ? "right" : "left";
let inputRect = this._getBoundsWithoutFlushing(this.input.textbox);
let startOffset = Math.abs(inputRect[boundToCheck] - documentRect[boundToCheck]);
@ -377,12 +376,10 @@ class UrlbarView {
this.panel.style.setProperty("--item-padding-start", px(start));
this.panel.style.setProperty("--item-padding-end", px(endOffset));
contentWidth -= start + endOffset;
} else {
this.panel.style.removeProperty("--item-padding-start");
this.panel.style.removeProperty("--item-padding-end");
}
this.panel.style.setProperty("--item-content-width", px(contentWidth));
// Align the panel with the input's parent toolbar.
let toolbarRect =
@ -683,13 +680,15 @@ class UrlbarView {
}
_on_overflow(event) {
if (event.target.classList.contains("urlbarView-row-inner")) {
if (event.target.classList.contains("urlbarView-url") ||
event.target.classList.contains("urlbarView-title")) {
event.target.toggleAttribute("overflow", true);
}
}
_on_underflow(event) {
if (event.target.classList.contains("urlbarView-row-inner")) {
if (event.target.classList.contains("urlbarView-url") ||
event.target.classList.contains("urlbarView-title")) {
event.target.toggleAttribute("overflow", false);
}
}

View File

@ -37,7 +37,6 @@ function createContext(searchString = "foo", properties = {}) {
let context = new UrlbarQueryContext({
allowAutofill: UrlbarPrefs.get("autoFill"),
isPrivate: true,
lastKey: searchString ? searchString[searchString.length - 1] : "",
maxResults: UrlbarPrefs.get("maxRichResults"),
searchString,
});

View File

@ -11,22 +11,12 @@ add_task(function test_constructor() {
Assert.throws(() => new UrlbarQueryContext({
allowAutofill: true,
isPrivate: false,
maxResults: 1,
searchString: "foo",
}), /Missing or empty lastKey provided to UrlbarQueryContext/,
"Should throw with a missing lastKey parameter");
Assert.throws(() => new UrlbarQueryContext({
allowAutofill: true,
isPrivate: false,
lastKey: "b",
searchString: "foo",
}), /Missing or empty maxResults provided to UrlbarQueryContext/,
"Should throw with a missing maxResults parameter");
Assert.throws(() => new UrlbarQueryContext({
allowAutofill: true,
lastKey: "b",
maxResults: 1,
searchString: "foo",
}), /Missing or empty isPrivate provided to UrlbarQueryContext/,
@ -34,7 +24,6 @@ add_task(function test_constructor() {
Assert.throws(() => new UrlbarQueryContext({
isPrivate: false,
lastKey: "b",
maxResults: 1,
searchString: "foo",
}), /Missing or empty allowAutofill provided to UrlbarQueryContext/,
@ -43,7 +32,6 @@ add_task(function test_constructor() {
let qc = new UrlbarQueryContext({
allowAutofill: false,
isPrivate: true,
lastKey: "b",
maxResults: 1,
searchString: "foo",
});
@ -52,8 +40,6 @@ add_task(function test_constructor() {
"Should have saved the correct value for allowAutofill");
Assert.strictEqual(qc.isPrivate, true,
"Should have saved the correct value for isPrivate");
Assert.equal(qc.lastKey, "b",
"Should have saved the correct value for lastKey");
Assert.equal(qc.maxResults, 1,
"Should have saved the correct value for maxResults");
Assert.equal(qc.searchString, "foo",

View File

@ -103,7 +103,7 @@ var testData = [
new keywordResult(null, null, true)],
];
AddonTestUtils.init(this);
AddonTestUtils.init(this, false);
AddonTestUtils.overrideCertDB();
AddonTestUtils.createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");

View File

@ -12,7 +12,7 @@ const {AddonTestUtils} = ChromeUtils.import("resource://testing-common/AddonTest
const SUGGEST_PREF = "browser.urlbar.suggest.searches";
const SUGGEST_ENABLED_PREF = "browser.search.suggest.enabled";
AddonTestUtils.init(this);
AddonTestUtils.init(this, false);
AddonTestUtils.overrideCertDB();
AddonTestUtils.createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");

View File

@ -25,6 +25,9 @@ export CFLAGS="--coverage"
export CXXFLAGS="--coverage"
export LDFLAGS="--coverage -Wl,--compress-debug-sections=zlib"
# gold is required for libFuzzer to work properly
ac_add_options --enable-gold
ac_add_options --enable-fuzzing
unset MOZ_STDCXX_COMPAT

View File

@ -15,6 +15,9 @@ ac_add_options --enable-valgrind
. $topsrcdir/build/unix/mozconfig.asan
ac_add_options --disable-elf-hack
# gold is required for libFuzzer to work properly
ac_add_options --enable-gold
ac_add_options --enable-fuzzing
unset MOZ_STDCXX_COMPAT

View File

@ -56,3 +56,56 @@
- vi
- zh-CN
- zh-TW
- type: show-url
# yamllint disable-line rule:line-length
url: "https://www.mozilla.org/%LOCALE%/{product}/{version.major_number}.0beta/whatsnew/?oldversion=%OLD_VERSION%"
conditions:
blob-types: [wnp]
release-types: [beta, release-rc]
products: [firefox]
update-channel: beta
# e.g.: ["<61.0"]. {version.major_number} reflects the current version.
# This is done by taskgraph.
versions: ["<{version.major_number}.0"]
locales:
- be
- cak
- cs
- cy
- da
- de
- dsb
- en-CA
- en-GB
- en-US
- es-AR
- es-CL
- es-ES
- es-MX
- fr
- fy-NL
- gn
- hsb
- hu
- ia
- id
- it
- ka
- lij
- nl
- nn-NO
- pl
- pt-BR
- pt-PT
- rm
- ro
- ru
- sk
- sl
- sq
- sv-SE
- tr
- uk
- vi
- zh-CN
- zh-TW

View File

@ -60,9 +60,6 @@ It is augmented as it progresses through the system, with various information:
// whether to include autofill results, but when false, no
// provider should include them.
isPrivate; // {boolean} Whether the search started in a private context.
lastKey; // {string} The last key pressed by the user. This can affect the
// behavior, for example by not autofilling again when the user
// hit backspace.
maxResults; // {integer} The maximum number of results requested. It is
// possible to request more results than the shown ones, and
// do additional filtering at the View level.

View File

@ -5,7 +5,6 @@
<title>Test basic autofill</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="../formautofill_common.js"></script>
<script type="text/javascript" src="../../../../../..//toolkit/components/satchel/test/satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test form autofill - clear form button</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="../formautofill_common.js"></script>
<script type="text/javascript" src="../../../../../../toolkit/components/satchel/test/satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test basic autofill</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="../formautofill_common.js"></script>
<script type="text/javascript" src="../../../../../../toolkit/components/satchel/test/satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -1,6 +1,5 @@
/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SimpleTest.js */
/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/EventUtils.js */
/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
/* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
/* eslint-disable no-unused-vars */

View File

@ -5,7 +5,6 @@
<title>Test autofill submission for a country without address-level1</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test autofill submit</title>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test basic autofill</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test basic autofill</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test basic autofill</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test form autofill - preview and highlight</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test basic autofill</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test autofill submit</title>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -5,7 +5,6 @@
<title>Test autofill submit</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />

View File

@ -1,4 +1,4 @@
@media screen and (min-device-width:481px) {
@media (any-pointer: fine) {
:root {
font-family: sans-serif;
margin: 40px auto;
@ -78,7 +78,7 @@
}
}
@media screen and (min-device-width:320px) and (max-device-width:480px) {
@media (any-pointer: coarse), (any-pointer: none) {
* {
margin: 0;
padding: 0;

View File

@ -131,7 +131,7 @@ function redrawTable(table, data) {
const bug = row.bug;
a.href = `https://bugzilla.mozilla.org/show_bug.cgi?id=${bug}`;
document.l10n.setAttributes(a, "label-more-information", {bug});
a.target = "aboutCompatBug";
a.target = "_blank";
td.appendChild(a);
tr.appendChild(td);

View File

@ -131,7 +131,7 @@ for (const override of [
* To receive the proper mobile version instead of the desktop version or
* a lower grade mobile experience, the UA is spoofed.
*/
id: "bug1177298",
id: "bug1177298-1",
platform: "android",
domain: "weather.yahoo.co.jp",
bug: "1177298",
@ -149,7 +149,7 @@ for (const override of [
* To receive the proper mobile version instead of the desktop version or
* a lower grade mobile experience, the UA is spoofed.
*/
id: "bug1177298",
id: "bug1177298-2",
platform: "android",
domain: "lohaco.jp",
bug: "1177298",
@ -167,7 +167,7 @@ for (const override of [
* To receive the proper mobile version instead of the desktop version or
* a lower grade mobile experience, the UA is spoofed.
*/
id: "bug1177298",
id: "bug1177298-3",
platform: "android",
domain: "nhk.or.jp",
bug: "1177298",
@ -185,7 +185,7 @@ for (const override of [
* To receive the proper mobile version instead of the desktop version or
* a lower grade mobile experience, the UA is spoofed.
*/
id: "bug1177298",
id: "bug1177298-4",
platform: "android",
domain: "uniqlo.com",
bug: "1177298",

View File

@ -60,7 +60,11 @@ containers-color-pink =
.label = Pink
containers-color-purple =
.label = Purple
containers-color-toolbar =
.label = Match toolbar
containers-icon-fence =
.label = Fence
containers-icon-fingerprint =
.label = Fingerprint
containers-icon-briefcase =

View File

@ -49,27 +49,30 @@
border-radius: 2px;
fill: currentColor;
fill-opacity: .6;
padding-top: 5px;
padding-bottom: 5px;
padding-top: 6px;
padding-bottom: 6px;
padding-inline-start: calc(var(--item-padding-start, calc(5px + @urlbarViewFaviconOffset@)) - @urlbarViewFaviconOffset@);
padding-inline-end: var(--item-padding-end, 5px);
}
:root[uidensity=touch] .urlbarView-row {
padding-top: 10px;
padding-bottom: 10px;
padding-top: 11px;
padding-bottom: 11px;
}
.urlbarView-row-inner {
overflow: hidden;
display: block;
display: flex;
flex-wrap: nowrap;
align-items: end;
justify-content: start;
}
.urlbarView-row-inner[overflow] {
.urlbarView-title[overflow],
.urlbarView-url[overflow] {
mask-image: linear-gradient(to left, transparent, black 2em);
}
.urlbarView-row-inner[overflow]:-moz-locale-dir(rtl) {
.urlbarView-title[overflow]:-moz-locale-dir(rtl) {
mask-image: linear-gradient(to right, transparent, black 2em);
}
@ -87,8 +90,7 @@
.urlbarView-favicon {
display: inline-block;
vertical-align: middle;
transform: translateY(-2px);
width: 16px;
min-width: 16px;
height: 16px;
margin-inline-end: @urlbarViewIconMarginEnd@;
background-repeat: no-repeat;
@ -117,8 +119,10 @@
vertical-align: text-bottom;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: calc(var(--item-content-width) * .7 - 2 * (16px + @urlbarViewIconMarginEnd@));
/* We prioritize the title over the url, so it can grow freely, but it should
never crop the url completely */
flex-shrink: 0;
max-width: calc(70% - 2 * (16px + @urlbarViewIconMarginEnd@));
}
.urlbarView-title-separator::before {
@ -148,6 +152,7 @@
}
.urlbarView-url {
overflow: hidden;
color: var(--urlbar-popup-url-color);
}
@ -172,6 +177,7 @@
.urlbarView-tags {
display: inline-block;
overflow: hidden;
}
.urlbarView-tag {

View File

@ -42,6 +42,15 @@
"/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include"
],
"api_level": 21
},
"x86_64-linux-android": {
"ndk_toolchain": "/builds/worker/workspace/build/src/android-ndk/toolchains/x86_64-4.9/prebuilt/linux-x86_64",
"ndk_sysroot": "/builds/worker/workspace/build/src/android-ndk/platforms/android-21/arch-x86_64",
"ndk_includes": [
"/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include/x86_64-linux-android",
"/builds/worker/workspace/build/src/android-ndk/sysroot/usr/include"
],
"api_level": 21
}
},
"patches": [

View File

@ -4,32 +4,62 @@
# 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/.
# cbindgen is needed by the style system build.
cbindgen = check_prog('CBINDGEN', ['cbindgen'], paths=toolchain_search_path,
when=depends(build_project)
(lambda build_project: build_project != 'js'))
# cbindgen is needed by the style system build and webrender.
cbindgen_is_needed = depends(build_project)(lambda build_project: build_project != 'js')
option(env='CBINDGEN', nargs=1, when=cbindgen_is_needed,
help='Path to cbindgen')
@depends_if(cbindgen)
@checking('cbindgen version')
@imports(_from='textwrap', _import='dedent')
def cbindgen_version(cbindgen):
def check_cbindgen_version(cbindgen, fatal=False):
log.debug("trying cbindgen: %s" % cbindgen)
cbindgen_min_version = Version('0.8.3')
# cbindgen x.y.z
version = Version(check_cmd_output(cbindgen, '--version').strip().split(" ")[1])
log.debug("%s has version %s" % (cbindgen, version))
if version >= cbindgen_min_version:
return True
if not fatal:
return False
if version < cbindgen_min_version:
die(dedent('''\
cbindgen version {} is too old. At least version {} is required.
die(dedent('''\
cbindgen version {} is too old. At least version {} is required.
Please update using 'cargo install cbindgen --force' or running
'./mach bootstrap', after removing the existing executable located at
{}.
'''.format(version, cbindgen_min_version, cbindgen)))
Please update using 'cargo install cbindgen --force' or running
'./mach bootstrap', after removing the existing executable located at
{}.
'''.format(version, cbindgen_min_version, cbindgen)))
return version
@depends_if('CBINDGEN', toolchain_search_path, when=cbindgen_is_needed)
@checking('for cbindgen')
@imports(_from='textwrap', _import='dedent')
def cbindgen(cbindgen_override, toolchain_search_path):
if cbindgen_override:
check_cbindgen_version(cbindgen_override[0], fatal=True)
return cbindgen_override[0]
candidates = []
for path in toolchain_search_path:
candidate = find_program('cbindgen', [path])
if not candidate:
continue
if check_cbindgen_version(candidate):
return candidate
candidates.append(candidate)
if not candidates:
raise FatalCheckError(dedent('''\
Cannot find cbindgen. Please run `mach bootstrap`,
`cargo install cbindgen`, ensure that `cbindgen` is on your PATH,
or point at an executable with `CBINDGEN`.
'''))
check_cbindgen_version(candidates[0], fatal=True)
set_config('CBINDGEN', cbindgen)
# Bindgen can use rustfmt to format Rust file, but it's not required.
js_option(env='RUSTFMT', nargs=1, help='Path to the rustfmt program')

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -178,6 +178,11 @@ http://another-tracking.example.net:80
http://itisatracker.org:80
https://itisatracker.org:443
http://trackertest.org:80
#
# Used while testing TLS session ticket resumption for third-party trackers (bug 1500533)
# (DO NOT USE THIS HOST IN OTHER TESTS!)
#
https://tlsresumptiontest.example.org:443
https://malware.example.com:443
https://unwanted.example.com:443

View File

@ -46,6 +46,15 @@ const {
const Actions = require("./index");
function isCachedActorNeeded(runtime, type, id) {
// Unique ids for workers were introduced in Firefox 68 (Bug 1539328). When debugging
// older browsers, the id falls back to the actor ID. Check if the target id is a worker
// actorID (which means getActor() should return an actor with id).
// Can be removed when Firefox 68 is in Release channel.
return type === DEBUG_TARGETS.WORKER &&
runtime.runtimeDetails.clientWrapper.client.getActor(id);
}
function getTabForUrl(url) {
for (const navigator of Services.wm.getEnumerator("navigator:browser")) {
for (const browser of navigator.gBrowser.browsers) {
@ -61,10 +70,10 @@ function getTabForUrl(url) {
function inspectDebugTarget(type, id) {
return async (dispatch, getState) => {
const runtime = getCurrentRuntime(getState().runtimes);
const remoteId = remoteClientManager.getRemoteId(runtime.id, runtime.type);
id = encodeURIComponent(id);
let url;
if (runtime.id === RUNTIMES.THIS_FIREFOX && type !== DEBUG_TARGETS.WORKER) {
if (runtime.id === RUNTIMES.THIS_FIREFOX && !isCachedActorNeeded(runtime, type, id)) {
// Even when debugging on This Firefox we need to re-use the client since the worker
// actor is cached in the client instance. Instead we should pass an id that does
// not depend on the client (such as the worker url). This will be fixed in
@ -76,6 +85,7 @@ function inspectDebugTarget(type, id) {
// will fail. See Bug 1534201.
url = `about:devtools-toolbox?type=${type}&id=${id}`;
} else {
const remoteId = remoteClientManager.getRemoteId(runtime.id, runtime.type);
url = `about:devtools-toolbox?type=${type}&id=${id}&remoteId=${remoteId}`;
}

View File

@ -4,6 +4,8 @@
"use strict";
const Services = require("Services");
const Actions = require("./index");
const {
@ -23,6 +25,7 @@ const { remoteClientManager } =
require("devtools/client/shared/remote-debugging/remote-client-manager");
const {
CONNECT_RUNTIME_CANCEL,
CONNECT_RUNTIME_FAILURE,
CONNECT_RUNTIME_NOT_RESPONDING,
CONNECT_RUNTIME_START,
@ -54,6 +57,7 @@ const {
} = require("../constants");
const CONNECTION_TIMING_OUT_DELAY = 3000;
const CONNECTION_CANCEL_DELAY = 13000;
async function getRuntimeIcon(channel) {
return (channel === "release" || channel === "beta" || channel === "aurora")
@ -73,12 +77,29 @@ function onMultiE10sUpdated() {
function connectRuntime(id) {
return async (dispatch, getState) => {
dispatch({ type: CONNECT_RUNTIME_START, id });
// The preferences test-connection-timing-out-delay and test-connection-cancel-delay
// don't have a default value but will be overridden during our tests.
const connectionTimingOutDelay = Services.prefs.getIntPref(
"devtools.aboutdebugging.test-connection-timing-out-delay",
CONNECTION_TIMING_OUT_DELAY);
const connectionCancelDelay = Services.prefs.getIntPref(
"devtools.aboutdebugging.test-connection-cancel-delay", CONNECTION_CANCEL_DELAY);
const connectionNotRespondingTimer = setTimeout(() => {
// If connecting to the runtime takes time over CONNECTION_TIMING_OUT_DELAY,
// we assume the connection prompt is showing on the runtime, show a dialog
// to let user know that.
dispatch({ type: CONNECT_RUNTIME_NOT_RESPONDING, id });
}, CONNECTION_TIMING_OUT_DELAY);
}, connectionTimingOutDelay);
const connectionCancelTimer = setTimeout(() => {
// Connect button of the runtime will be disabled during connection, but the status
// continues till the connection was either succeed or failed. This may have a
// possibility that the disabling continues unless page reloading, user will not be
// able to click again. To avoid this, revert the connect button status after
// CONNECTION_CANCEL_DELAY ms.
dispatch({ type: CONNECT_RUNTIME_CANCEL, id });
}, connectionCancelDelay);
try {
const runtime = findRuntimeById(id, getState().runtimes);
@ -148,6 +169,7 @@ function connectRuntime(id) {
dispatch({ type: CONNECT_RUNTIME_FAILURE, id, error: e });
} finally {
clearTimeout(connectionNotRespondingTimer);
clearTimeout(connectionCancelTimer);
}
};
}
@ -159,6 +181,7 @@ function createThisFirefoxRuntime() {
isConnecting: false,
isConnectionFailed: false,
isConnectionNotResponding: false,
isConnectionTimeout: false,
isUnavailable: false,
isUnplugged: false,
name: l10n.getString("about-debugging-this-firefox-runtime-name"),
@ -321,8 +344,10 @@ function updateNetworkRuntimes(locations) {
isConnecting: false,
isConnectionFailed: false,
isConnectionNotResponding: false,
isConnectionTimeout: false,
isUnavailable: false,
isUnplugged: false,
isUnknown: false,
name: location,
type: RUNTIMES.NETWORK,
};
@ -345,6 +370,7 @@ function updateUSBRuntimes(adbRuntimes) {
isConnecting: false,
isConnectionFailed: false,
isConnectionNotResponding: false,
isConnectionTimeout: false,
isUnavailable: adbRuntime.isUnavailable,
isUnplugged: adbRuntime.isUnplugged,
name: adbRuntime.shortName,
@ -363,7 +389,7 @@ function updateUSBRuntimes(adbRuntimes) {
function _isRuntimeValid(runtime, runtimes) {
const isRuntimeAvailable = runtimes.some(r => r.id === runtime.id);
const isConnectionValid = runtime.runtimeDetails &&
!runtime.runtimeDetails.clientWrapper.isClosed();
!runtime.runtimeDetails.clientWrapper.isClosed();
return isRuntimeAvailable && isConnectionValid;
}
@ -374,7 +400,7 @@ function updateRemoteRuntimes(runtimes, type) {
// Check if the updated remote runtimes should trigger a navigation out of the current
// runtime page.
if (currentRuntime && currentRuntime.type === type &&
!_isRuntimeValid(currentRuntime, runtimes)) {
!_isRuntimeValid(currentRuntime, runtimes)) {
// Since current remote runtime is invalid, move to this firefox page.
// This case is considered as followings and so on:
// * Remove ADB addon
@ -394,16 +420,19 @@ function updateRemoteRuntimes(runtimes, type) {
// - isConnectionFailed (set by about:debugging if connection was failed)
// - isConnectionNotResponding
// (set by about:debugging if connection is taking too much time)
// - isConnectionTimeout (set by about:debugging if connection was timeout)
runtimes.forEach(runtime => {
const existingRuntime = findRuntimeById(runtime.id, getState().runtimes);
const isConnectionValid = existingRuntime && existingRuntime.runtimeDetails &&
!existingRuntime.runtimeDetails.clientWrapper.isClosed();
!existingRuntime.runtimeDetails.clientWrapper.isClosed();
runtime.runtimeDetails = isConnectionValid ? existingRuntime.runtimeDetails : null;
runtime.isConnecting = existingRuntime ? existingRuntime.isConnecting : false;
runtime.isConnectionFailed =
existingRuntime ? existingRuntime.isConnectionFailed : false;
runtime.isConnectionNotResponding =
existingRuntime ? existingRuntime.isConnectionNotResponding : false;
runtime.isConnectionTimeout =
existingRuntime ? existingRuntime.isConnectionTimeout : false;
});
const existingRuntimes = getAllRuntimes(getState().runtimes);

View File

@ -116,6 +116,7 @@ class Sidebar extends PureComponent {
isConnecting: runtime.isConnecting,
isConnectionFailed: runtime.isConnectionFailed,
isConnectionNotResponding: runtime.isConnectionNotResponding,
isConnectionTimeout: runtime.isConnectionTimeout,
isSelected,
isUnavailable: runtime.isUnavailable,
isUnplugged: runtime.isUnplugged,

View File

@ -31,6 +31,7 @@ class SidebarRuntimeItem extends PureComponent {
isConnecting: PropTypes.bool.isRequired,
isConnectionFailed: PropTypes.bool.isRequired,
isConnectionNotResponding: PropTypes.bool.isRequired,
isConnectionTimeout: PropTypes.bool.isRequired,
isSelected: PropTypes.bool.isRequired,
isUnavailable: PropTypes.bool.isRequired,
isUnplugged: PropTypes.bool.isRequired,
@ -62,46 +63,16 @@ class SidebarRuntimeItem extends PureComponent {
);
}
renderConnectionError() {
const { isConnectionFailed } = this.props;
if (!isConnectionFailed) {
renderMessage(flag, level, localizationId, className) {
if (!flag) {
return null;
}
const localizationId =
"about-debugging-sidebar-item-connect-button-connection-failed";
return Message(
{
level: MESSAGE_LEVEL.ERROR,
key: "connection-error",
className: "qa-connection-error",
},
Localized(
{
id: localizationId,
},
dom.p({ className: "word-wrap-anywhere" }, localizationId)
)
);
}
renderConnectionNotResponding() {
const { isConnectionNotResponding } = this.props;
if (!isConnectionNotResponding) {
return null;
}
const localizationId =
"about-debugging-sidebar-item-connect-button-connection-not-responding";
return Message(
{
level: MESSAGE_LEVEL.WARNING,
key: "connection-not-responding",
className: "qa-connection-not-responding",
level,
key: className,
className,
},
Localized(
{
@ -176,6 +147,9 @@ class SidebarRuntimeItem extends PureComponent {
getString,
icon,
isConnected,
isConnectionFailed,
isConnectionTimeout,
isConnectionNotResponding,
isSelected,
isUnavailable,
runtimeId,
@ -209,8 +183,24 @@ class SidebarRuntimeItem extends PureComponent {
!isUnavailable && !isConnected ? this.renderConnectButton() : null
),
),
this.renderConnectionError(),
this.renderConnectionNotResponding(),
this.renderMessage(
isConnectionFailed,
MESSAGE_LEVEL.ERROR,
"about-debugging-sidebar-item-connect-button-connection-failed",
"qa-connection-error"
),
this.renderMessage(
isConnectionTimeout,
MESSAGE_LEVEL.ERROR,
"about-debugging-sidebar-item-connect-button-connection-timeout",
"qa-connection-timeout"
),
this.renderMessage(
isConnectionNotResponding,
MESSAGE_LEVEL.WARNING,
"about-debugging-sidebar-item-connect-button-connection-not-responding",
"qa-connection-not-responding"
),
];
}
}

View File

@ -15,6 +15,7 @@ const actionTypes = {
ADB_ADDON_UNINSTALL_SUCCESS: "ADB_ADDON_UNINSTALL_SUCCESS",
ADB_ADDON_UNINSTALL_FAILURE: "ADB_ADDON_UNINSTALL_FAILURE",
ADB_ADDON_STATUS_UPDATED: "ADB_ADDON_STATUS_UPDATED",
CONNECT_RUNTIME_CANCEL: "CONNECT_RUNTIME_CANCEL",
CONNECT_RUNTIME_FAILURE: "CONNECT_RUNTIME_FAILURE",
CONNECT_RUNTIME_NOT_RESPONDING: "CONNECT_RUNTIME_NOT_RESPONDING",
CONNECT_RUNTIME_START: "CONNECT_RUNTIME_START",

View File

@ -50,18 +50,13 @@ function toComponentData(workers, isServiceWorker) {
const icon = "chrome://devtools/skin/images/debugging-workers.svg";
let { fetch } = worker;
const {
id,
name,
registrationFront,
scope,
subscription,
workerTargetFront,
} = worker;
// For registering service workers, workerTargetFront will not be available.
// The only valid identifier we can use at that point is the actorID for the
// service worker registration.
const id = workerTargetFront ? workerTargetFront.actorID : registrationFront.actorID;
let pushServiceEndpoint = null;
let status = null;

View File

@ -145,9 +145,7 @@ class ClientWrapper {
}
async getServiceWorkerFront({ id }) {
const { serviceWorkers } = await this.listWorkers();
const workerFronts = serviceWorkers.map(sw => sw.workerTargetFront);
return workerFronts.find(front => front && front.actorID === id);
return this.client.mainRoot.getWorker(id);
}
async listWorkers() {

View File

@ -5,6 +5,7 @@
"use strict";
const {
CONNECT_RUNTIME_CANCEL,
CONNECT_RUNTIME_FAILURE,
CONNECT_RUNTIME_NOT_RESPONDING,
CONNECT_RUNTIME_START,
@ -81,6 +82,7 @@ function runtimesReducer(state = RuntimesState(), action) {
isConnecting: true,
isConnectionFailed: false,
isConnectionNotResponding: false,
isConnectionTimeout: false,
};
return _updateRuntimeById(id, updatedState, state);
}
@ -90,6 +92,17 @@ function runtimesReducer(state = RuntimesState(), action) {
return _updateRuntimeById(id, { isConnectionNotResponding: true }, state);
}
case CONNECT_RUNTIME_CANCEL: {
const { id } = action;
const updatedState = {
isConnecting: false,
isConnectionFailed: false,
isConnectionNotResponding: false,
isConnectionTimeout: true,
};
return _updateRuntimeById(id, updatedState, state);
}
case CONNECT_RUNTIME_SUCCESS: {
const { id, runtimeDetails, type } = action.runtime;
remoteClientManager.setClient(id, type, runtimeDetails.clientWrapper.client);
@ -97,6 +110,7 @@ function runtimesReducer(state = RuntimesState(), action) {
isConnecting: false,
isConnectionFailed: false,
isConnectionNotResponding: false,
isConnectionTimeout: false,
runtimeDetails,
};
return _updateRuntimeById(id, updatedState, state);
@ -108,6 +122,7 @@ function runtimesReducer(state = RuntimesState(), action) {
isConnecting: false,
isConnectionFailed: true,
isConnectionNotResponding: false,
isConnectionTimeout: false,
};
return _updateRuntimeById(id, updatedState, state);
}

View File

@ -126,6 +126,9 @@ const runtime = {
// or failing.
isConnectionNotResponding: PropTypes.bool.isRequired,
// this flag will be true when the connection was timeout.
isConnectionTimeout: PropTypes.bool.isRequired,
// unavailable runtimes are placeholders for devices where the runtime has not been
// started yet. For instance an ADB device connected without a compatible runtime
// running.

View File

@ -8,11 +8,16 @@ const RUNTIME_NAME = "test runtime name";
const RUNTIME_DEVICE_NAME = "test device name";
const RUNTIME_SHORT_NAME = "test short name";
const CONNECTION_TIMING_OUT_DELAY = 1000;
const CONNECTION_CANCEL_DELAY = 2000;
// Test following connection state tests.
// * Connect button label and state will change during connecting.
// * Show error message if connection failed.
// * Show warninng if connection has been taken time.
add_task(async function() {
await setupPreferences();
const mocks = new Mocks();
const { document, tab } = await openAboutDebugging();
@ -51,11 +56,11 @@ add_task(async function() {
info("Click on the connect button and wait until it disappears");
connectButton.click();
info("Check whether a warning of connection not responding displays after 3sec");
info("Check whether a warning of connection not responding displays");
await waitUntil(() => document.querySelector(".qa-connection-not-responding"));
ok(document.querySelector(".qa-connection-not-responding"),
"A warning of connection not responding displays");
ok(connectButton.disabled, "State of the connect button displays");
ok(connectButton.disabled, "Connect button is disabled");
ok(connectButton.textContent.startsWith("Connecting"),
"Label of the connect button changes");
ok(!document.querySelector(".qa-connection-error"), "Error message disappears");
@ -73,3 +78,65 @@ add_task(async function() {
await removeTab(tab);
});
// Test whether the status of all will be reverted after a certain period of time during
// waiting connection.
add_task(async function() {
await setupPreferences();
const mocks = new Mocks();
const { document, tab } = await openAboutDebugging();
mocks.createUSBRuntime(RUNTIME_ID, {
name: RUNTIME_NAME,
deviceName: RUNTIME_DEVICE_NAME,
shortName: RUNTIME_SHORT_NAME,
});
mocks.emitUSBUpdate();
info("Wait until the USB sidebar item appears");
await waitUntil(() => findSidebarItemByText(RUNTIME_DEVICE_NAME, document));
const usbRuntimeSidebarItem = findSidebarItemByText(RUNTIME_DEVICE_NAME, document);
const connectButton = usbRuntimeSidebarItem.querySelector(".js-connect-button");
let resumeConnection;
const resumeConnectionPromise = new Promise(r => {
resumeConnection = r;
});
mocks.runtimeClientFactoryMock.createClientForRuntime = async (runtime) => {
await resumeConnectionPromise;
return mocks._clients[runtime.type][runtime.id];
};
info("Click on the connect button and wait until it disappears");
connectButton.click();
await waitUntil(() => document.querySelector(".qa-connection-not-responding"));
info("Check whether the all status will be reverted");
await waitUntil(() => !document.querySelector(".qa-connection-not-responding"));
ok(document.querySelector(".qa-connection-timeout"),
"Connection timeout message displays");
ok(!connectButton.disabled, "Connect button is enabled");
is(connectButton.textContent, "Connect", "Label of the connect button reverted");
ok(!document.querySelector(".qa-connection-error"), "Error message disappears");
info("Check whether the timeout message disappears");
resumeConnection();
await waitUntil(() => !document.querySelector(".qa-connection-timeout"));
info("Remove a USB runtime");
mocks.removeUSBRuntime(RUNTIME_ID);
mocks.emitUSBUpdate();
info("Wait until the USB sidebar item disappears");
await waitUntilUsbDeviceIsUnplugged(RUNTIME_DEVICE_NAME, document);
await removeTab(tab);
});
async function setupPreferences() {
await pushPref("devtools.aboutdebugging.test-connection-timing-out-delay",
CONNECTION_TIMING_OUT_DELAY);
await pushPref("devtools.aboutdebugging.test-connection-cancel-delay",
CONNECTION_CANCEL_DELAY);
}

View File

@ -8,12 +8,9 @@ const { gDevToolsBrowser } = require("devtools/client/framework/devtools-browser
add_task(async function() {
const thisFirefoxClient = createThisFirefoxClientMock();
// Prepare a worker mock.
const testWorkerTargetFront = {
actorID: "test-worker-id",
};
const testWorker = {
id: "test-worker-id",
name: "Test Worker",
workerTargetFront: testWorkerTargetFront,
};
// Add a worker mock as other worker.
thisFirefoxClient.listWorkers = () => ({
@ -21,9 +18,13 @@ add_task(async function() {
serviceWorkers: [],
sharedWorkers: [],
});
// Override getActor function of client which is used in inspect action for worker.
thisFirefoxClient.client.getActor = id => {
return id === testWorkerTargetFront.actorID ? testWorkerTargetFront : null;
// Override getActor of client and getWorker function of root of client
// which is used in inspect action for worker.
thisFirefoxClient.client.getActor = id => null;
thisFirefoxClient.client.mainRoot = {
getWorker: id => {
return id === testWorker.id ? testWorker : null;
},
};
const runtimeClientFactoryMock = createRuntimeClientFactoryMock();
@ -52,8 +53,8 @@ add_task(async function() {
info("Check whether the correct actor front will be opened in worker toolbox");
const url = new window.URL(devtoolsWindow.location.href);
const workderID = url.searchParams.get("id");
is(workderID, testWorkerTargetFront.actorID,
const workerID = url.searchParams.get("id");
is(workerID, testWorker.id,
"Correct actor front will be opened in worker toolbox");
await removeTab(devtoolsTab);

View File

@ -88,6 +88,12 @@ async function openAboutDevtoolsToolbox(doc, tab, win, targetText = "about:debug
await waitUntil(() =>
devtoolsBrowser.contentWindow.location.href.startsWith("about:devtools-toolbox?"));
if (!shouldWaitToolboxReady) {
// Wait for show error page.
await waitUntil(() =>
devtoolsBrowser.contentDocument.querySelector(".js-error-page"));
}
return {
devtoolsBrowser,
devtoolsDocument: devtoolsBrowser.contentDocument,

View File

@ -9,6 +9,7 @@ const {
FILTER_TOGGLE,
FILTERS,
RESET,
SELECT,
} = require("../constants");
/**
@ -50,6 +51,7 @@ function audit(state = getInitialState(), action) {
...state,
auditing: null,
};
case SELECT:
case RESET:
return getInitialState();
default:

View File

@ -24,6 +24,7 @@ skip-if = (os == 'linux' && debug && bits == 64) # Bug 1511247
[browser_accessibility_reload.js]
[browser_accessibility_sidebar_checks.js]
[browser_accessibility_sidebar.js]
[browser_accessibility_tree_audit_reset.js]
[browser_accessibility_tree_audit_toolbar.js]
[browser_accessibility_tree_audit.js]
[browser_accessibility_tree_contrast.js]

View File

@ -0,0 +1,88 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/* global toggleFilter, selectAccessibleForNode */
const TEST_URI = `<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Panel Test</title>
</head>
<body>
<h1 style="color:rgba(255,0,0,0.1); background-color:rgba(255,255,255,1);">
Top level header
</h1>
<h2 style="color:rgba(0,255,0,0.1); background-color:rgba(255,255,255,1);">
Second level header
</h2>
</body>
</html>`;
/**
* Test data has the format of:
* {
* desc {String} description for better logging
* setup {Function} An optional setup that needs to be performed before
* the state of the tree and the sidebar can be checked.
* expected {JSON} An expected states for the tree and the sidebar.
* }
*/
const tests = [{
desc: "Check initial state.",
expected: {
tree: [{
role: "document",
name: `"Accessibility Panel Test"`,
}],
},
}, {
desc: "Run an audit from a11y panel toolbar by activating a filter.",
setup: async ({ doc }) => {
await toggleFilter(doc, 0);
},
expected: {
tree: [{
role: "text leaf",
name: `"Top level header "contrast`,
badges: [ "contrast" ],
}, {
role: "text leaf",
name: `"Second level header "contrast`,
badges: [ "contrast" ],
}],
},
}, {
desc: "Select an accessible object.",
setup: async (env) => {
await selectAccessibleForNode(env, "body");
},
expected: {
tree: [{
role: "document",
name: `"Accessibility Panel Test"`,
}, {
role: "heading",
name: `"Top level header"`,
}, {
role: "text leaf",
name: `"Top level header "contrast`,
badges: [ "contrast" ],
}, {
role: "heading",
name: `"Second level header"`,
}, {
role: "text leaf",
name: `"Second level header "contrast`,
badges: [ "contrast" ],
}],
},
}];
/**
* Simple test that checks content of the Accessibility panel tree when the
* audit is activated via the panel's toolbar.
*/
addA11yPanelTestsTask(tests, TEST_URI,
"Test Accessibility panel tree with contrast filter audit activation.");

View File

@ -409,6 +409,23 @@ async function toggleFilter(doc, filterIndex) {
expected === filter.classList.contains("checked"), "Filter updated.");
}
async function findAccessibleFor({
toolbox: { walker: domWalker },
panel: { walker: a11yWalker },
}, selector) {
const node = await domWalker.querySelector(domWalker.rootNode, selector);
return a11yWalker.getAccessibleFor(node);
}
async function selectAccessibleForNode(env, selector) {
const { panel, win } = env;
const front = await findAccessibleFor(env, selector);
const { EVENTS } = win;
const onSelected = win.once(EVENTS.NEW_ACCESSIBLE_FRONT_SELECTED);
panel.selectAccessible(front);
await onSelected;
}
/**
* Iterate over setups/tests structure and test the state of the
* accessibility panel.

View File

@ -0,0 +1,6 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="context-fill" d="M8 1a7 7 0 1 0 7 7 7.008 7.008 0 0 0-7-7zm0 13a6 6 0 1 1 6-6 6.007 6.007 0 0 1-6 6zm0-7a1 1 0 0 0-1 1v3a1 1 0 1 0 2 0V8a1 1 0 0 0-1-1zm0-3.188A1.188 1.188 0 1 0 9.188 5 1.188 1.188 0 0 0 8 3.812z"></path>
</svg>

After

Width:  |  Height:  |  Size: 540 B

View File

@ -27,6 +27,7 @@ DevToolsModules(
'globe.svg',
'help.svg',
'home.svg',
'info.svg',
'loader.svg',
'next-circle.svg',
'next.svg',

View File

@ -58,6 +58,7 @@ import WelcomeBox from "./WelcomeBox";
import EditorTabs from "./Editor/Tabs";
import EditorFooter from "./Editor/Footer";
import QuickOpenModal from "./QuickOpenModal";
import WhyPaused from "./SecondaryPanes/WhyPaused";
type Props = {
selectedSource: Source,
@ -234,6 +235,9 @@ class App extends Component<Props, State> {
startPanelSize={startPanelSize}
endPanelSize={endPanelSize}
/>
{this.props.endPanelCollapsed ? (
<WhyPaused horizontal={horizontal} />
) : null}
{!this.props.selectedSource ? (
<WelcomeBox
horizontal={horizontal}

View File

@ -21,7 +21,6 @@ import {
} from "../../../utils/breakpoint";
import { getSelectedLocation } from "../../../utils/source-maps";
import { features } from "../../../utils/prefs";
import { getEditor } from "../../../utils/editor";
import type {
Breakpoint as BreakpointType,
@ -30,6 +29,7 @@ import type {
SourceLocation,
Context
} from "../../../types";
import type SourceEditor from "../../../utils/editor/source-editor";
type FormattedFrame = Frame & {
selectedLocation: SourceLocation
@ -50,6 +50,7 @@ type Props = {
selectedSource: Source,
source: Source,
frame: FormattedFrame,
editor: SourceEditor,
enableBreakpoint: typeof actions.enableBreakpoint,
removeBreakpoint: typeof actions.removeBreakpoint,
removeBreakpoints: typeof actions.removeBreakpoints,
@ -137,22 +138,16 @@ class Breakpoint extends PureComponent<Props> {
highlightText = memoize(
(text = "", editor) => {
if (!editor.CodeMirror) {
return { __html: text };
}
const node = document.createElement("div");
editor.CodeMirror.runMode(text, "application/javascript", node);
return { __html: node.innerHTML };
},
(text, editor) => `${text} - ${editor.CodeMirror ? "editor" : ""}`
text => text
);
/* eslint-disable react/no-danger */
render() {
const { breakpoint } = this.props;
const { breakpoint, editor } = this.props;
const text = this.getBreakpointText();
const editor = getEditor();
const labelId = `${breakpoint.id}-label`;
return (

View File

@ -16,6 +16,7 @@ import BreakpointHeading from "./BreakpointHeading";
import actions from "../../../actions";
import { getDisplayPath } from "../../../utils/source";
import { getSelectedLocation } from "../../../utils/source-maps";
import { createHeadlessEditor } from "../../../utils/editor/create-editor";
import {
makeBreakpointId,
@ -30,6 +31,7 @@ import {
import type { Source } from "../../../types";
import type { BreakpointSources } from "../../../selectors/breakpointSources";
import type SourceEditor from "../../../utils/editor/source-editor";
import "./Breakpoints.css";
@ -43,6 +45,27 @@ type Props = {
};
class Breakpoints extends Component<Props> {
headlessEditor: ?SourceEditor;
componentWillUnmount() {
this.removeEditor();
}
getEditor(): SourceEditor {
if (!this.headlessEditor) {
this.headlessEditor = createHeadlessEditor();
}
return this.headlessEditor;
}
removeEditor() {
if (!this.headlessEditor) {
return;
}
this.headlessEditor.destroy();
this.headlessEditor = (null: any);
}
renderExceptionsOptions() {
const {
breakpointSources,
@ -111,6 +134,7 @@ class Breakpoints extends Component<Props> {
breakpoint={breakpoint}
source={source}
selectedSource={selectedSource}
editor={this.getEditor()}
key={makeBreakpointId(
getSelectedLocation(breakpoint, selectedSource)
)}

View File

@ -87,6 +87,13 @@ function generateDefaults(overrides = {}, breakpointOverrides = {}) {
breakpoint,
selectedSource,
frame: (null: any),
editor: {
CodeMirror: {
runMode: function() {
return "";
}
}
},
...overrides
};
}

View File

@ -1,37 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
.why-paused {
display: flex;
background-color: var(--theme-body-background);
color: var(--theme-body-color);
opacity: 0.6;
font-size: 12px;
text-align: center;
font-style: italic;
font-weight: 300;
cursor: default;
min-height: 24px;
white-space: normal;
}
.why-paused > div {
margin: auto;
}
.theme-dark .secondary-panes .why-paused {
color: white;
}
.why-paused .message {
padding: 4px;
font-size: 10px;
}
.why-paused .message.warning {
font-size: 10px;
color: var(--theme-graphs-red);
font-weight: bold;
font-style: normal;
}

View File

@ -1,58 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
// @flow
import React from "react";
import { getPauseReason } from "../../../utils/pause";
import type { Grip, ExceptionReason } from "../../../types";
import "./WhyPaused.css";
function renderExceptionSummary(exception: string | Grip) {
if (typeof exception === "string") {
return exception;
}
const preview = exception.preview;
if (!preview || !preview.name || !preview.message) {
return;
}
return `${preview.name}: ${preview.message}`;
}
function renderMessage(why: ExceptionReason) {
if (why.type == "exception" && why.exception) {
return (
<div className={"message warning"}>
{renderExceptionSummary(why.exception)}
</div>
);
}
if (typeof why.message == "string") {
return <div className={"message"}>{why.message}</div>;
}
return null;
}
export default function renderWhyPaused(why: Object) {
const reason = getPauseReason(why);
if (!reason) {
return null;
}
return (
<div className={"pane why-paused"}>
<div>
<div>{L10N.getStr(reason)}</div>
{renderMessage(why)}
</div>
</div>
);
}
renderWhyPaused.displayName = "whyPaused";

View File

@ -8,13 +8,11 @@ import React, { Component } from "react";
import { connect } from "../../../utils/connect";
import PropTypes from "prop-types";
import type { Frame, Why, ThreadContext } from "../../../types";
import type { Frame, ThreadContext } from "../../../types";
import FrameComponent from "./Frame";
import Group from "./Group";
import renderWhyPaused from "./WhyPaused";
import actions from "../../../actions";
import { collapseFrames, formatCopyName } from "../../../utils/pause/frames";
import { copyToTheClipboard } from "../../../utils/clipboard";
@ -23,7 +21,6 @@ import {
getFrameworkGroupingState,
getSelectedFrame,
getCallStackFrames,
getPauseReason,
getCurrentThread,
getThreadContext
} from "../../../selectors";
@ -37,7 +34,6 @@ type Props = {
frames: Array<Frame>,
frameworkGroupingOn: boolean,
selectedFrame: Object,
why: Why,
selectFrame: typeof actions.selectFrame,
toggleBlackBox: Function,
toggleFrameworkGrouping: Function,
@ -196,7 +192,7 @@ class Frames extends Component<Props, State> {
}
render() {
const { frames, disableFrameTruncate, why } = this.props;
const { frames, disableFrameTruncate } = this.props;
if (!frames) {
return (
@ -211,7 +207,6 @@ class Frames extends Component<Props, State> {
return (
<div className="pane frames">
{this.renderFrames(frames)}
{renderWhyPaused(why)}
{disableFrameTruncate ? null : this.renderToggleButton(frames)}
</div>
);
@ -223,7 +218,6 @@ Frames.contextTypes = { l10n: PropTypes.object };
const mapStateToProps = state => ({
cx: getThreadContext(state),
frames: getCallStackFrames(state),
why: getPauseReason(state, getCurrentThread(state)),
frameworkGroupingOn: getFrameworkGroupingState(state),
selectedFrame: getSelectedFrame(state, getCurrentThread(state))
});

View File

@ -13,11 +13,9 @@ CompiledModules(
'FrameMenu.js',
'Group.js',
'index.js',
'WhyPaused.js',
)
DevToolsModules(
'Frames.css',
'Group.css',
'WhyPaused.css',
)

View File

@ -0,0 +1,52 @@
/* 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/>. */
.why-paused {
display: flex;
flex-direction: column;
justify-content: center;
border-bottom: 1px solid var(--theme-splitter-color);
background-color: hsl(54, 100%, 92%);
color: var(--theme-body-color);
font-size: 12px;
cursor: default;
min-height: 44px;
padding: 4px;
white-space: normal;
font-weight: bold;
}
.why-paused > div {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.why-paused .info.icon {
align-self: center;
padding: 0px 4px;
}
.why-paused .pause.reason {
display: flex;
flex-direction: column;
padding-left: 16px;
padding-right: 4px;
}
.theme-dark .secondary-panes .why-paused {
background-color: hsl(42, 37%, 19%);
color: hsl(43, 94%, 81%);
}
.why-paused .message {
font-style: italic;
font-weight: 100;
}
.why-paused .message.warning {
color: var(--theme-graphs-red);
font-weight: bold;
font-style: italic;
}

View File

@ -0,0 +1,110 @@
/* 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/>. */
// @flow
import React, { PureComponent } from "react";
import { connect } from "../../utils/connect";
import AccessibleImage from "../shared/AccessibleImage";
import { getPauseReason } from "../../utils/pause";
import {
getCurrentThread,
getPaneCollapse,
getPauseReason as getWhy
} from "../../selectors";
import type { Grip, ExceptionReason } from "../../types";
import "./WhyPaused.css";
type Props = {
endPanelCollapsed: boolean,
delay: ?number,
why: ExceptionReason
};
type State = {
hideWhyPaused: string
};
class WhyPaused extends PureComponent<Props, State> {
constructor(props) {
super(props);
this.state = { hideWhyPaused: "" };
}
componentDidUpdate() {
const { delay } = this.props;
if (delay) {
setTimeout(() => {
this.setState({ hideWhyPaused: "" });
}, delay);
} else {
this.setState({ hideWhyPaused: "pane why-paused" });
}
}
renderExceptionSummary(exception: string | Grip) {
if (typeof exception === "string") {
return exception;
}
const preview = exception.preview;
if (!preview || !preview.name || !preview.message) {
return;
}
return `${preview.name}: ${preview.message}`;
}
renderMessage(why: ExceptionReason) {
if (why.type == "exception" && why.exception) {
return (
<div className={"message warning"}>
{this.renderExceptionSummary(why.exception)}
</div>
);
}
if (typeof why.message == "string") {
return <div className={"message"}>{why.message}</div>;
}
return null;
}
render() {
const { endPanelCollapsed, why } = this.props;
const reason = getPauseReason(why);
if (reason) {
if (!endPanelCollapsed) {
return (
<div className={"pane why-paused"}>
<div>
<div className="pause reason">
{L10N.getStr(reason)}
{this.renderMessage(why)}
</div>
<div className="info icon">
<AccessibleImage className="info" />
</div>
</div>
</div>
);
}
}
return <div className={this.state.hideWhyPaused} />;
}
}
const mapStateToProps = state => {
const thread = getCurrentThread(state);
return {
endPanelCollapsed: getPaneCollapse(state, "end"),
why: getWhy(state, thread)
};
};
export default connect(mapStateToProps)(WhyPaused);

View File

@ -16,6 +16,7 @@ import {
getBreakpointsDisabled,
getExpressions,
getIsWaitingOnBreak,
getPauseCommand,
isMapScopesEnabled,
getSelectedFrame,
getShouldPauseOnExceptions,
@ -38,6 +39,7 @@ import CommandBar from "./CommandBar";
import UtilsBar from "./UtilsBar";
import XHRBreakpoints from "./XHRBreakpoints";
import EventListeners from "./EventListeners";
import WhyPaused from "./WhyPaused";
import Scopes from "./Scopes";
@ -81,6 +83,7 @@ type Props = {
selectedFrame: ?Frame,
breakpointsDisabled: boolean,
isWaitingOnBreak: boolean,
renderWhyPauseDelay: number,
mapScopesEnabled: boolean,
shouldPauseOnExceptions: boolean,
shouldPauseOnCaughtExceptions: boolean,
@ -360,8 +363,9 @@ class SecondaryPanes extends Component<Props, State> {
getStartItems(): AccordionPaneItem[] {
const items: AccordionPaneItem[] = [];
const { horizontal, hasFrames } = this.props;
if (this.props.horizontal) {
if (horizontal) {
if (features.workers && this.props.workers.length > 0) {
items.push(this.getWorkersItem());
}
@ -371,9 +375,9 @@ class SecondaryPanes extends Component<Props, State> {
items.push(this.getBreakpointsItem());
if (this.props.hasFrames) {
if (hasFrames) {
items.push(this.getCallStackItem());
if (this.props.horizontal) {
if (horizontal) {
items.push(this.getScopeItem());
}
}
@ -413,19 +417,33 @@ class SecondaryPanes extends Component<Props, State> {
}
renderHorizontalLayout() {
return <Accordion items={this.getItems()} />;
const { renderWhyPauseDelay } = this.props;
return (
<div>
<WhyPaused delay={renderWhyPauseDelay} />
<Accordion items={this.getItems()} />
</div>
);
}
renderVerticalLayout() {
return (
<SplitBox
initialSize="300px"
minSize={10}
maxSize="50%"
splitterSize={1}
startPanel={<Accordion items={this.getStartItems()} />}
endPanel={<Accordion items={this.getEndItems()} />}
/>
<div>
<SplitBox
initialSize="300px"
minSize={10}
maxSize="50%"
splitterSize={1}
startPanel={
<div style={{ width: "inherit" }}>
<WhyPaused delay={this.props.renderWhyPauseDelay} />
<Accordion items={this.getStartItems()} />
</div>
}
endPanel={<Accordion items={this.getEndItems()} />}
/>
</div>
);
}
@ -457,6 +475,18 @@ class SecondaryPanes extends Component<Props, State> {
}
}
// Checks if user is in debugging mode and adds a delay preventing
// excessive vertical 'jumpiness'
function getRenderWhyPauseDelay(state, thread) {
const inPauseCommand = !!getPauseCommand(state, thread);
if (!inPauseCommand) {
return 100;
}
return 0;
}
const mapStateToProps = state => {
const thread = getCurrentThread(state);
@ -467,6 +497,7 @@ const mapStateToProps = state => {
breakpoints: getBreakpointsList(state),
breakpointsDisabled: getBreakpointsDisabled(state),
isWaitingOnBreak: getIsWaitingOnBreak(state, thread),
renderWhyPauseDelay: getRenderWhyPauseDelay(state, thread),
selectedFrame: getSelectedFrame(state, thread),
mapScopesEnabled: isMapScopesEnabled(state),
shouldPauseOnExceptions: getShouldPauseOnExceptions(state),

View File

@ -15,6 +15,7 @@ CompiledModules(
'index.js',
'Scopes.js',
'UtilsBar.js',
'WhyPaused.js',
'Worker.js',
'Workers.js',
'XHRBreakpoints.js',
@ -26,6 +27,7 @@ DevToolsModules(
'Expressions.css',
'Scopes.css',
'SecondaryPanes.css',
'WhyPaused.css',
'Workers.css',
'XHRBreakpoints.css',
)

Some files were not shown because too many files have changed in this diff Show More