Merge autoland to mozilla-central. a=merge

This commit is contained in:
Noemi Erli 2019-10-04 00:47:14 +03:00
Родитель a1961739be 20802e4942
Коммит 38eb5bb32a
91 изменённых файлов: 2150 добавлений и 1204 удалений

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1569844523596">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1570053270833">
<emItems>
<emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
<prefs/>
@ -3461,6 +3461,30 @@
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="21f14cff-afef-4e0e-97e8-4dbc0207a7a6" id="mozilla_cc3@internetdownloadmanager.com">
<prefs/>
<versionRange minVersion="0" maxVersion="6.35.5" severity="3"/>
</emItem>
<emItem blockID="87d99543-1e31-46b3-9fd1-91d9c79ff592" id="{d41cf5b5-67b7-4510-8633-d8e2c0ec5d46}">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="9a12e67a-ef6d-4f06-9de6-7dc8bcb19517" id="{5dbbb375-3520-4ace-bb84-df9d92ae1a25}">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="4e487385-fe8d-451a-909e-a6f6609b0d7b" id="/^((\{6be4ca4f-8b7e-4d91-994b-24a7c5384086\})|(\{1709abf0-19ba-48a8-a9dc-03e931b17f48\})|(\{5d5af81d-6501-4d77-a64c-ad2cdc34ceae\})|(\{b7de0a65-0b4b-4b74-a4e6-70fc2c36a80a\})|(\{64704bd2-ced7-4dd8-a5d2-d20df624288f\}))$/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="a942e2e5-6a55-439f-b078-6288da1cfe68" id="/^((\{049aedf7-b1dc-49b7-9ef4-51cd026f8592\})|(\{27c743d8-4731-44ff-9194-9f663df6a3c3\})|(\{8bf2bae7-273a-4496-9073-c1ad6688cda8\})|(\{b9cfeaaa-2465-4b21-903a-7955fcd4e59a\})|(\{07848e3a-f42b-48bf-ac70-f918a7b79258\})|(\{02b2eed4-2ca5-4d6f-b19a-a8b1738501f0\})|(\{d2af93ad-a542-4b30-b929-7437c2b02afe\})|(\{b8e33742-5b78-4c08-89e1-94ebe22fbafe\})|(\{502b29ef-b05f-4043-949b-069160f39e32\})|(\{2c60eb88-2f38-4b1a-9329-eaa18ad41720\})|(\{ccb18b6f-0680-4347-afd5-5ed864114f05\})|(\{c9622009-2b37-44f1-a5cf-f0aa869a6bff\})|(\{cc241172-6e33-4395-bc68-dd76fa6b6091\})|(\{904a47b7-c2c3-465d-a7f9-326c51e8fee0\})|(\{365ae96e-15f8-445f-816e-74cd5897613c\})|(\{527ccde6-f15c-4437-a061-052593c2ac5b\})|(\{063b5c1a-b708-4f05-873b-b3e161d1d49a\})|(\{d5422b3f-fcb3-4eca-b2a9-b4b8010fd4c1\})|(\{60bab1b2-e7fc-4683-85ef-2ec6cdb5e148\})|(\{aad32311-3e2f-419d-8e6b-82c4e28c44d3\}))$/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="6ce8f6d0-5cef-457c-b7e4-d5c08d61531a" id="{67d4f93e-6857-45ab-9e7a-158cc61f15d2}">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
</emItems>
<pluginItems>
<pluginItem blockID="p332">

Просмотреть файл

@ -166,6 +166,7 @@ let LEGACY_ACTORS = {
"AboutLogins:LoginRemoved",
"AboutLogins:MasterPasswordResponse",
"AboutLogins:SendFavicons",
"AboutLogins:SetBreaches",
"AboutLogins:Setup",
"AboutLogins:ShowLoginItemError",
"AboutLogins:SyncState",

Просмотреть файл

@ -219,6 +219,9 @@ class AboutLoginsChild extends ActorChild {
case "AboutLogins:SendFavicons":
this.sendToContent("SendFavicons", message.data);
break;
case "AboutLogins:SetBreaches":
this.sendToContent("SetBreaches", message.data);
break;
case "AboutLogins:Setup":
this.sendToContent("Setup", message.data);
Cu.waiveXrays(this.content).AboutLoginsUtils.masterPasswordEnabled =

Просмотреть файл

@ -242,7 +242,7 @@ var AboutLoginsParent = {
);
const messageManager = message.target.messageManager;
messageManager.sendAsyncMessage(
"AboutLogins:UpdateBreaches",
"AboutLogins:SetBreaches",
breachesByLoginGUID
);
break;
@ -460,12 +460,22 @@ var AboutLoginsParent = {
},
handleLoginStorageErrors(login, error, message) {
const messageManager = message.target.messageManager;
const errorMessage = error.message;
messageManager.sendAsyncMessage("AboutLogins:ShowLoginItemError", {
let messageObject = {
login: augmentVanillaLoginObject(LoginHelper.loginToVanillaObject(login)),
errorMessage,
});
errorMessage: error.message,
};
if (error.message.includes("This login already exists")) {
// See comment in LoginHelper.createLoginAlreadyExistsError as to
// why we need to call .toString() on the nsISupportsString.
messageObject.existingLoginGuid = error.data.toString();
}
const messageManager = message.target.messageManager;
messageManager.sendAsyncMessage(
"AboutLogins:ShowLoginItemError",
messageObject
);
},
async observe(subject, topic, type) {
@ -503,6 +513,13 @@ var AboutLoginsParent = {
return;
}
this.messageSubscribers("AboutLogins:LoginAdded", login);
if (BREACH_ALERTS_ENABLED) {
this.messageSubscribers(
"AboutLogins:UpdateBreaches",
await LoginBreaches.getPotentialBreachesByLoginGUID([login])
);
}
break;
}
case "modifyLogin": {
@ -715,7 +732,7 @@ var AboutLoginsParent = {
};
if (BREACH_ALERTS_ENABLED) {
sendMessageFn(
"AboutLogins:UpdateBreaches",
"AboutLogins:SetBreaches",
await LoginBreaches.getPotentialBreachesByLoginGUID(logins)
);
}

Просмотреть файл

@ -45,7 +45,9 @@
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/confirmation-dialog.css">
<div class="overlay">
<div class="container" role="dialog" aria-labelledby="title" aria-describedby="message">
<button class="dismiss-button" data-l10n-id="confirmation-dialog-dismiss-button"></button>
<button class="dismiss-button" data-l10n-id="confirmation-dialog-dismiss-button">
<img class="dismiss-icon" src="chrome://global/skin/icons/close.svg"/>
</button>
<div class="content">
<img class="warning-icon" src="chrome://global/skin/icons/warning.svg"/>
<h1 class="title" id="title"></h1>
@ -111,13 +113,13 @@
<template id="login-list-item-template">
<li class="login-list-item" role="option">
<div class="favicon-wrapper">
<img class="favicon" src="" alt=""/>
<img class="favicon" src=""/>
</div>
<div class="labels">
<span class="title" dir="auto"></span>
<span class="username" dir="ltr"></span>
</div>
<img data-l10n-id="about-logins-list-item-warning-icon" class="list-item-warning-icon" alt="" title="" src="chrome://global/skin/icons/warning.svg"/>
<img data-l10n-id="about-logins-list-item-breach-icon" class="list-item-warning-icon" title="" src="chrome://global/skin/icons/warning.svg"/>
</li>
</template>
@ -145,16 +147,22 @@
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/login-item.css">
<div class="error-message">
<span class="error-message-text"></span>
<span class="error-message-text" data-l10n-id="about-logins-error-message-default"></span>
<span class="error-message-link">
<a data-l10n-name="duplicate-link" href=""></a>
</span>
</div>
<div class="breach-alert">
<img class="breach-icon" src="chrome://global/skin/icons/warning.svg"/>
<span class="breach-alert-text" data-l10n-id="breach-alert-text"></span>
<a class="breach-alert-link" data-l10n-id="breach-alert-link" href="#" rel="noreferrer" target="_blank"></a>
<button class="dismiss-breach-alert"></button>
<button class="dismiss-breach-alert" data-l10n-id="breach-alert-dismiss">
<img class="dismiss-breach-alert-icon" src="chrome://global/skin/icons/close.svg"/>
</button>
</div>
<div class="header">
<div class="login-item-favicon-wrapper">
<img class="login-item-favicon" src="" alt=""/>
<img class="login-item-favicon" src=""/>
</div>
<h2 class="title">
<span class="login-item-title"></span>

Просмотреть файл

@ -69,6 +69,11 @@ window.addEventListener("AboutLoginsChromeToContent", event => {
gElements.loginList.addFavicons(event.detail.value);
break;
}
case "SetBreaches": {
gElements.loginList.setBreaches(event.detail.value);
gElements.loginItem.setBreaches(event.detail.value);
break;
}
case "Setup": {
handleAllLogins(event.detail.value.logins);
gElements.loginFooter.showStoreIconsForLocales(

Просмотреть файл

@ -14,10 +14,8 @@
.container {
z-index: 2;
position: relative;
display: flex;
flex-direction: column;
min-width: 250px;
max-width: 500px;
min-height: 200px;
@ -25,6 +23,8 @@
background: var(--in-content-page-background);
color: var(--in-content-page-color);
box-shadow: var(--shadow-30);
/* show a border in high contrast mode */
outline: 1px solid transparent;
}
.title {
@ -39,7 +39,7 @@
margin-bottom: 0;
}
button.dismiss-button {
.dismiss-button {
position: absolute;
top: 0;
inset-inline-end: 0;
@ -47,7 +47,10 @@ button.dismiss-button {
min-height: 20px;
margin: 16px;
padding: 0;
background: url(chrome://global/skin/icons/close.svg) no-repeat center;
line-height: 0;
}
.dismiss-icon {
-moz-context-properties: fill, fill-opacity;
fill: currentColor;
fill-opacity: 0;

Просмотреть файл

@ -44,7 +44,7 @@ export default class ConfirmationDialog extends HTMLElement {
case "click":
if (
event.target.classList.contains("cancel-button") ||
event.target.classList.contains("dismiss-button") ||
event.currentTarget.classList.contains("dismiss-button") ||
event.target.classList.contains("overlay")
) {
this.onCancel();

Просмотреть файл

@ -282,12 +282,7 @@ input[name="password"] {
border-radius: 8px;
border: 1px solid var(--in-content-border-color);
background-color: var(--yellow-10);
background-image: url("chrome://global/skin/icons/warning.svg");
background-repeat: no-repeat;
background-position: left 10px top 10px;
color: #0C0C0D;
-moz-context-properties: fill;
fill: var(--red-90);
box-shadow: 0 2px 8px 0 rgba(12,12,13,0.1);
font-size: .9em;
font-weight: 300;
@ -299,31 +294,30 @@ input[name="password"] {
position: relative;
}
.breach-alert:dir(rtl) {
background-position: right 10px top 10px;
}
a.breach-alert-link {
.breach-alert-link {
color: inherit;
text-decoration: underline;
font-weight: 500;
}
.breach-icon {
position: absolute;
inset-block-start: 10px;
inset-inline-start: 10px;
-moz-context-properties: fill;
fill: var(--red-90);
}
.dismiss-breach-alert {
border: none;
padding: 0;
margin: 0;
position: absolute;
background-image: url("chrome://global/skin/icons/close.svg");
background-repeat: no-repeat;
background-size: contain;
min-height: 16px;
min-width: 16px;
-moz-context-properties: fill, fill-opacity;
fill-opacity: 0;
fill: currentColor;
inset-inline-end: 12px;
inset-block-start: 12px;
min-width: auto;
min-height: auto;
line-height: 0;
}
.dismiss-breach-alert,
@ -331,6 +325,14 @@ a.breach-alert-link {
background-color: transparent;
}
.dismiss-breach-alert-icon {
-moz-context-properties: fill, fill-opacity;
fill-opacity: 0;
fill: currentColor;
width: 16px;
height: 16px;
}
.error-message {
color: #fff;
background-color: var(--red-60);
@ -351,6 +353,20 @@ a.breach-alert-link {
background-position-x: right 10px;
}
.error-message-link > a,
.error-message-link > a:hover,
.error-message-link > a:hover:active {
color: currentColor;
text-decoration: underline;
font-weight: 600;
}
@media (-moz-windows-default-theme: 0) {
.breach-icon {
fill: currentColor;
}
}
@supports -moz-bool-pref("browser.in-content.dark-mode") {
@media (prefers-color-scheme: dark) {
:host {

Просмотреть файл

@ -16,6 +16,7 @@ export default class LoginItem extends HTMLElement {
constructor() {
super();
this._login = {};
this._error = null;
this._copyUsernameTimeoutId = 0;
this._copyPasswordTimeoutId = 0;
}
@ -42,6 +43,12 @@ export default class LoginItem extends HTMLElement {
this._deleteButton = this.shadowRoot.querySelector(".delete-button");
this._editButton = this.shadowRoot.querySelector(".edit-button");
this._errorMessage = this.shadowRoot.querySelector(".error-message");
this._errorMessageLink = this._errorMessage.querySelector(
".error-message-link"
);
this._errorMessageText = this._errorMessage.querySelector(
".error-message-text"
);
this._form = this.shadowRoot.querySelector("form");
this._originInput = this.shadowRoot.querySelector("input[name='origin']");
this._usernameInput = this.shadowRoot.querySelector(
@ -74,18 +81,19 @@ export default class LoginItem extends HTMLElement {
this.render();
this._originInput.addEventListener("blur", this);
this._breachAlertLink.addEventListener("click", this);
this._cancelButton.addEventListener("click", this);
this._copyPasswordButton.addEventListener("click", this);
this._copyUsernameButton.addEventListener("click", this);
this._deleteButton.addEventListener("click", this);
this._dismissBreachAlert.addEventListener("click", this);
this._editButton.addEventListener("click", this);
this._errorMessageLink.addEventListener("click", this);
this._form.addEventListener("submit", this);
this._originInput.addEventListener("blur", this);
this._originInput.addEventListener("click", this);
this._revealCheckbox.addEventListener("click", this);
this._originInput.addEventListener("auxclick", this);
this._breachAlertLink.addEventListener("click", this);
this._revealCheckbox.addEventListener("click", this);
window.addEventListener("AboutLoginsInitialLoginSelected", this);
window.addEventListener("AboutLoginsLoadInitialFavicon", this);
window.addEventListener("AboutLoginsLoginSelected", this);
@ -94,35 +102,41 @@ export default class LoginItem extends HTMLElement {
focus() {
if (!this._breachAlert.hidden) {
const breachAlertLink = this._breachAlert.querySelector(
".breach-alert-link"
);
breachAlertLink.focus();
return;
}
if (!this._editButton.disabled) {
this._breachAlertLink.focus();
} else if (!this._editButton.disabled) {
this._editButton.focus();
return;
}
if (!this._deleteButton.disabled) {
} else if (!this._deleteButton.disabled) {
this._deleteButton.focus();
return;
} else {
this._originInput.focus();
}
this._originInput.focus();
}
async render() {
[this._errorMessage, this._breachAlert].forEach(el => {
el.hidden = true;
});
if (this._breachesMap && this._breachesMap.has(this._login.guid)) {
if (this._error) {
if (this._error.errorMessage.includes("This login already exists")) {
document.l10n.setAttributes(
this._errorMessageLink,
"about-logins-error-message-duplicate-login-with-link",
{
loginTitle: this._error.login.title,
}
);
this._errorMessageLink.dataset.errorGuid = this._error.existingLoginGuid;
this._errorMessageText.hidden = true;
this._errorMessageLink.hidden = false;
} else {
this._errorMessageText.hidden = false;
this._errorMessageLink.hidden = true;
}
}
this._errorMessage.hidden = !this._error;
this._breachAlert.hidden =
!this._breachesMap || !this._breachesMap.has(this._login.guid);
if (!this._breachAlert.hidden) {
const breachDetails = this._breachesMap.get(this._login.guid);
this._breachAlertLink.href = breachDetails.breachAlertURL;
document.l10n.setAttributes(
this._dismissBreachAlert,
"breach-alert-dismiss"
);
this._breachAlert.hidden = false;
}
document.l10n.setAttributes(this._timeCreated, "login-item-time-created", {
timeCreated: this._login.timeCreated || "",
@ -134,10 +148,6 @@ export default class LoginItem extends HTMLElement {
timeUsed: this._login.timeLastUsed || "",
});
document.l10n.setAttributes(this._favicon, "login-favicon", {
title: this._login.title,
});
if (this._login.faviconDataURI) {
this._faviconWrapper.classList.add("hide-default-favicon");
this._favicon.src = this._login.faviconDataURI;
@ -181,11 +191,21 @@ export default class LoginItem extends HTMLElement {
this._updatePasswordRevealState();
}
updateBreaches(breachesByLoginGUID) {
setBreaches(breachesByLoginGUID) {
this._breachesMap = breachesByLoginGUID;
this.render();
}
updateBreaches(breachesByLoginGUID) {
if (!this._breachesMap) {
this._breachesMap = new Map();
}
for (const [guid, breach] of [...breachesByLoginGUID]) {
this._breachesMap.set(guid, breach);
}
this.setBreaches(this._breachesMap);
}
dismissBreachAlert() {
document.dispatchEvent(
new CustomEvent("AboutLoginsDismissBreachAlert", {
@ -200,27 +220,8 @@ export default class LoginItem extends HTMLElement {
}
showLoginItemError(error) {
const errorMessageText = this._errorMessage.querySelector(
".error-message-text"
);
if (!error.errorMessage) {
return;
}
if (error.errorMessage.includes("This login already exists")) {
document.l10n.setAttributes(
errorMessageText,
"about-logins-error-message-duplicate-login",
{
loginTitle: error.login.title,
}
);
} else {
document.l10n.setAttributes(
errorMessageText,
"about-logins-error-message-default"
);
}
this._errorMessage.hidden = false;
this._error = error;
this.render();
}
async handleEvent(event) {
@ -376,6 +377,21 @@ export default class LoginItem extends HTMLElement {
});
return;
}
if (
event.originalTarget.dataset.l10nName == "duplicate-link" &&
event.currentTarget.dataset.errorGuid
) {
let existingDuplicateLogin = {
guid: event.currentTarget.dataset.errorGuid,
};
window.dispatchEvent(
new CustomEvent("AboutLoginsLoginSelected", {
detail: existingDuplicateLogin,
cancelable: true,
})
);
return;
}
if (classList.contains("origin-input")) {
this._handleOriginClick();
}
@ -512,6 +528,7 @@ export default class LoginItem extends HTMLElement {
*/
setLogin(login, { skipFocusChange } = {}) {
this._login = login;
this._error = null;
this._form.reset();

Просмотреть файл

@ -60,9 +60,6 @@ export default class LoginListItemFactory {
if (login.faviconDataURI) {
faviconWrapper.classList.add("hide-default-favicon");
favicon.src = login.faviconDataURI;
document.l10n.setAttributes(favicon, "login-favicon", {
title: login.title,
});
}
}
}

Просмотреть файл

@ -57,8 +57,7 @@
:host(.no-logins:not(.create-login-selected)) ol,
:host(:not(.no-logins)) .intro,
:host(.create-login-selected) .intro,
:host(.create-login-selected) .empty-search-message,
:host(:not(.create-login-selected)) #new-login-list-item {
:host(.create-login-selected) .empty-search-message {
display: none;
}
@ -172,13 +171,19 @@ ol {
display: none;
}
.breached > .list-item-warning-icon {
.list-item-warning-icon {
-moz-context-properties: fill;
fill: var(--red-90);
min-width: 16px;
margin-inline-start: 12px;
}
@media (-moz-windows-default-theme: 0) {
.list-item-warning-icon {
fill: currentColor;
}
}
@supports -moz-bool-pref("browser.in-content.dark-mode") {
@media (prefers-color-scheme: dark) {
.breached > .list-item-warning-icon {

Просмотреть файл

@ -118,6 +118,18 @@ export default class LoginList extends HTMLElement {
this._blankLoginListItem.nextElementSibling
);
}
let activeDescendantId = this._list.getAttribute("aria-activedescendant");
let activeDescendant =
activeDescendantId && this.shadowRoot.getElementById(activeDescendantId);
if (!activeDescendant || activeDescendant.hidden) {
let visibleListItem = this._list.querySelector(
".login-list-item:not([hidden])"
);
if (visibleListItem) {
this._list.setAttribute("aria-activedescendant", visibleListItem.id);
}
}
}
handleEvent(event) {
@ -159,9 +171,7 @@ export default class LoginList extends HTMLElement {
break;
}
case "change": {
this._applySort();
this.render();
this._list.scrollTop = 0;
this._applySortAndScrollToTop();
const extra = { sort_key: this._sortSelect.value };
recordTelemetryEvent({ object: "list", method: "sort", extra });
break;
@ -211,6 +221,22 @@ export default class LoginList extends HTMLElement {
return;
}
// XXX If an AboutLoginsLoginSelected event is received that doesn't contain
// the full login object, re-dispatch the event with the full login object since
// only the login-list knows the full details of each login object.
if (
Object.keys(event.detail).length == 1 &&
event.detail.hasOwnProperty("guid")
) {
window.dispatchEvent(
new CustomEvent("AboutLoginsLoginSelected", {
detail: this._logins[event.detail.guid].login,
cancelable: true,
})
);
return;
}
let listItem = this._list.querySelector(
`.login-list-item[data-guid="${event.detail.guid}"]`
);
@ -311,7 +337,7 @@ export default class LoginList extends HTMLElement {
* @param {Map} breachesByLoginGUID A Map of breaches by login GUIDs used
* for displaying breached login indicators.
*/
updateBreaches(breachesByLoginGUID) {
setBreaches(breachesByLoginGUID) {
this._breachesByLoginGUID = breachesByLoginGUID;
if (this._breachesByLoginGUID.size === 0) {
this.render();
@ -320,11 +346,22 @@ export default class LoginList extends HTMLElement {
const breachedSortOptionElement = this._sortSelect.namedItem("breached");
breachedSortOptionElement.hidden = false;
this._sortSelect.selectedIndex = breachedSortOptionElement.index;
this._sortSelect.dispatchEvent(new CustomEvent("input", { bubbles: true }));
this._sortSelect.dispatchEvent(
new CustomEvent("change", { bubbles: true })
);
this.render();
this._applySortAndScrollToTop();
}
/**
* @param {Map} breachesByLoginGUID A Map of breaches by login GUIDs that
* should be added to the local cache of
* breaches.
*/
updateBreaches(breachesByLoginGUID) {
if (!this._breachesByLoginGUID) {
this._breachesByLoginGUID = new Map();
}
for (const [guid, breach] of [...breachesByLoginGUID]) {
this._breachesByLoginGUID.set(guid, breach);
}
this.setBreaches(this._breachesByLoginGUID);
}
/**
@ -434,6 +471,12 @@ export default class LoginList extends HTMLElement {
});
}
_applySortAndScrollToTop() {
this._applySort();
this.render();
this._list.scrollTop = 0;
}
_updateVisibleLoginCount(count) {
if (count != document.l10n.getAttributes(this._count).args.count) {
document.l10n.setAttributes(this._count, "login-list-count", {
@ -499,6 +542,7 @@ export default class LoginList extends HTMLElement {
switch (event.key) {
case "ArrowDown": {
if (!nextItem) {
this._list.removeAttribute("aria-activedescendant");
return;
}
newlyFocusedItem = nextItem;
@ -507,6 +551,7 @@ export default class LoginList extends HTMLElement {
case "ArrowLeft": {
let item = isLTR ? previousItem : nextItem;
if (!item) {
this._list.removeAttribute("aria-activedescendant");
return;
}
newlyFocusedItem = item;
@ -515,6 +560,7 @@ export default class LoginList extends HTMLElement {
case "ArrowRight": {
let item = isLTR ? nextItem : previousItem;
if (!item) {
this._list.removeAttribute("aria-activedescendant");
return;
}
newlyFocusedItem = item;
@ -522,6 +568,7 @@ export default class LoginList extends HTMLElement {
}
case "ArrowUp": {
if (!previousItem) {
this._list.removeAttribute("aria-activedescendant");
return;
}
newlyFocusedItem = previousItem;
@ -533,6 +580,9 @@ export default class LoginList extends HTMLElement {
activeDescendant.click();
return;
}
case "Tab":
newlyFocusedItem = activeDescendant;
break;
default:
return;
}
@ -549,7 +599,14 @@ export default class LoginList extends HTMLElement {
oldSelectedItem.classList.remove("selected");
oldSelectedItem.removeAttribute("aria-selected");
}
let oldKeyboardSelectedItem = this._list.querySelector(
".keyboard-selected"
);
if (oldKeyboardSelectedItem) {
oldKeyboardSelectedItem.classList.remove("keyboard-selected");
}
this.classList.toggle("create-login-selected", !listItem.dataset.guid);
this._blankLoginListItem.hidden = !!listItem.dataset.guid;
this._createLoginButton.disabled = !listItem.dataset.guid;
listItem.classList.add("selected");
listItem.setAttribute("aria-selected", "true");

Просмотреть файл

@ -10,6 +10,7 @@ support-files =
skip-if = asan || debug
[browser_breachAlertDismissals.js]
skip-if = asan || debug || verify # bug 1574023
[browser_breachAlertShowingForAddedLogin.js]
[browser_confirmDeleteDialog.js]
[browser_contextmenuFillLogins.js]
[browser_copyToClipboardButton.js]

Просмотреть файл

@ -6,19 +6,23 @@ requestLongerTimeout(2);
ChromeUtils.import("resource://testing-common/TelemetryTestUtils.jsm", this);
ChromeUtils.import("resource://testing-common/LoginTestUtils.jsm", this);
EXPECTED_BREACH = {
AddedDate: "2018-12-20T23:56:26Z",
BreachDate: "2018-12-16",
Domain: "breached.example.com",
Name: "Breached",
PwnCount: 1643100,
DataClasses: ["Email addresses", "Usernames", "Passwords", "IP addresses"],
_status: "synced",
id: "047940fe-d2fd-4314-b636-b4a952ee0043",
last_modified: "1541615610052",
schema: "1541615609018",
};
add_task(async function setup() {
let storageChangedPromised = TestUtils.topicObserved(
"passwordmgr-storage-changed",
(_, data) => data == "addLogin"
);
TEST_LOGIN1 = Services.logins.addLogin(TEST_LOGIN1);
await storageChangedPromised;
storageChangedPromised = TestUtils.topicObserved(
"passwordmgr-storage-changed",
(_, data) => data == "addLogin"
);
TEST_LOGIN2 = Services.logins.addLogin(TEST_LOGIN2);
await storageChangedPromised;
TEST_LOGIN1 = await addLogin(TEST_LOGIN1);
TEST_LOGIN2 = await addLogin(TEST_LOGIN2);
TEST_LOGIN3 = await addLogin(TEST_LOGIN3);
await BrowserTestUtils.openNewForegroundTab({
gBrowser,
url: "about:logins",
@ -68,7 +72,7 @@ add_task(async function test_telemetry_events() {
let promiseNewTab = BrowserTestUtils.waitForNewTab(
gBrowser,
TEST_LOGIN2.origin + "/"
TEST_LOGIN3.origin + "/"
);
await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
let loginItem = content.document.querySelector("login-item");
@ -76,7 +80,7 @@ add_task(async function test_telemetry_events() {
originInput.click();
});
let newTab = await promiseNewTab;
ok(true, "New tab opened to " + TEST_LOGIN2.origin);
ok(true, "New tab opened to " + TEST_LOGIN3.origin);
BrowserTestUtils.removeTab(newTab);
await LoginTestUtils.telemetry.waitForEventCount(5);

Просмотреть файл

@ -1,24 +1,18 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
let { LoginBreaches } = ChromeUtils.import(
"resource:///modules/LoginBreaches.jsm"
);
const TEST_BREACHES = [
{
AddedDate: "2019-12-20T23:56:26Z",
BreachDate: "2018-12-16",
Domain: "breached.com",
Name: "Breached",
PwnCount: 1643100,
DataClasses: ["Email addresses", "Usernames", "Passwords", "IP addresses"],
_status: "synced",
id: "047940fe-d2fd-4314-b636-b4a952ee0043",
last_modified: "1541615610052",
schema: "1541615609018",
},
];
EXPECTED_BREACH = {
AddedDate: "2018-12-20T23:56:26Z",
BreachDate: "2018-12-16",
Domain: "breached.example.com",
Name: "Breached",
PwnCount: 1643100,
DataClasses: ["Email addresses", "Usernames", "Passwords", "IP addresses"],
_status: "synced",
id: "047940fe-d2fd-4314-b636-b4a952ee0043",
last_modified: "1541615610052",
schema: "1541615609018",
};
add_task(async function setup() {
TEST_LOGIN3 = await addLogin(TEST_LOGIN3);
@ -34,16 +28,7 @@ add_task(async function setup() {
add_task(async function test_show_login() {
let browser = gBrowser.selectedBrowser;
TEST_LOGIN3.timePasswordChanged = 12345;
let testBreaches = await LoginBreaches.getPotentialBreachesByLoginGUID(
[TEST_LOGIN3],
TEST_BREACHES
);
browser.messageManager.sendAsyncMessage(
"AboutLogins:UpdateBreaches",
testBreaches
);
await ContentTask.spawn(browser, TEST_LOGIN3, async () => {
await ContentTask.spawn(browser, null, async () => {
let loginItem = Cu.waiveXrays(content.document.querySelector("login-item"));
let breachAlert = loginItem.shadowRoot.querySelector(".breach-alert");
let breachAlertVisible = await ContentTaskUtils.waitForCondition(() => {

Просмотреть файл

@ -0,0 +1,60 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
EXPECTED_BREACH = {
AddedDate: "2018-12-20T23:56:26Z",
BreachDate: "2018-12-16",
Domain: "breached.example.com",
Name: "Breached",
PwnCount: 1643100,
DataClasses: ["Email addresses", "Usernames", "Passwords", "IP addresses"],
_status: "synced",
id: "047940fe-d2fd-4314-b636-b4a952ee0043",
last_modified: "1541615610052",
schema: "1541615609018",
};
add_task(async function setup() {
await BrowserTestUtils.openNewForegroundTab({
gBrowser,
url: "about:logins",
});
registerCleanupFunction(() => {
BrowserTestUtils.removeTab(gBrowser.selectedTab);
Services.logins.removeAllLogins();
});
});
add_task(async function test_added_login_shows_breach_warning() {
let browser = gBrowser.selectedBrowser;
await ContentTask.spawn(browser, null, async () => {
let loginList = Cu.waiveXrays(content.document.querySelector("login-list"));
is(
loginList._loginGuidsSortedOrder.length,
0,
"the login list should be empty"
);
});
TEST_LOGIN3 = await addLogin(TEST_LOGIN3);
await ContentTask.spawn(browser, TEST_LOGIN3.guid, async aTestLogin3Guid => {
let loginList = Cu.waiveXrays(content.document.querySelector("login-list"));
is(
loginList._loginGuidsSortedOrder.length,
1,
"one login should be in the list"
);
let breachedLoginListItems;
await ContentTaskUtils.waitForCondition(() => {
breachedLoginListItems = loginList._list.querySelectorAll(
".login-list-item[data-guid].breached"
);
return breachedLoginListItems.length == 1;
}, "waiting for the login to get marked as breached");
is(
breachedLoginListItems[0].dataset.guid,
aTestLogin3Guid,
"the breached login should be login3"
);
});
});

Просмотреть файл

@ -394,3 +394,77 @@ add_task(async function test_cancel_create_login_with_logins_filtered_out() {
);
});
});
add_task(async function test_create_duplicate_login() {
let browser = gBrowser.selectedBrowser;
await ContentTask.spawn(browser, null, async () => {
let loginList = Cu.waiveXrays(content.document.querySelector("login-list"));
let createButton = loginList._createLoginButton;
createButton.click();
let loginItem = Cu.waiveXrays(content.document.querySelector("login-item"));
let originInput = loginItem.shadowRoot.querySelector(
"input[name='origin']"
);
let usernameInput = loginItem.shadowRoot.querySelector(
"input[name='username']"
);
let passwordInput = loginItem.shadowRoot.querySelector(
"input[name='password']"
);
const EXISTING_ORIGIN = "https://example.com";
const EXISTING_USERNAME = "testuser2";
originInput.value = EXISTING_ORIGIN;
usernameInput.value = EXISTING_USERNAME;
passwordInput.value = "different password value";
let saveChangesButton = loginItem.shadowRoot.querySelector(
".save-changes-button"
);
saveChangesButton.click();
await ContentTaskUtils.waitForCondition(
() => !loginItem._errorMessage.hidden,
"waiting until the error message is visible"
);
let duplicatedGuid = Object.values(loginList._logins).find(
v =>
v.login.origin == EXISTING_ORIGIN &&
v.login.username == EXISTING_USERNAME
).login.guid;
is(
loginItem._errorMessageLink.dataset.errorGuid,
duplicatedGuid,
"Error message has GUID of existing duplicated login set on it"
);
let confirmationDialog = Cu.waiveXrays(
content.document.querySelector("confirmation-dialog")
);
ok(
confirmationDialog.hidden,
"the discard-changes dialog should be hidden before clicking the error-message-text"
);
loginItem._errorMessageLink.querySelector("a").click();
ok(
!confirmationDialog.hidden,
"the discard-changes dialog should be visible"
);
let discardChangesButton = confirmationDialog.shadowRoot.querySelector(
".confirm-button"
);
discardChangesButton.click();
await ContentTaskUtils.waitForCondition(
() =>
Object.keys(loginItem._login).length > 1 &&
loginItem._login.guid == duplicatedGuid,
"waiting until the existing duplicated login is selected"
);
is(
loginList._selectedGuid,
duplicatedGuid,
"the duplicated login should be selected in the list"
);
});
});

Просмотреть файл

@ -81,11 +81,11 @@ add_task(async function test_showLoginItemErrors() {
);
const loginItemErrorMessageText = loginItemErrorMessage.querySelector(
"span"
"span:not([hidden])"
);
ok(
loginItemErrorMessageText.dataset.l10nId ===
"about-logins-error-message-duplicate-login",
is(
loginItemErrorMessageText.dataset.l10nId,
"about-logins-error-message-duplicate-login-with-link",
"The correct error message is displayed."
);

Просмотреть файл

@ -81,7 +81,7 @@ add_task(async function test_query_parameter_filter() {
);
let hiddenLoginListItems = loginList.shadowRoot.querySelectorAll(
".login-list-item[hidden]"
".login-list-item:not(#new-login-list-item)[hidden]"
);
let visibleLoginListItems = loginList.shadowRoot.querySelectorAll(
".login-list-item:not(#new-login-list-item):not([hidden])"

Просмотреть файл

@ -1,6 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
let { LoginBreaches } = ChromeUtils.import(
"resource:///modules/LoginBreaches.jsm"
);
let { RemoteSettings } = ChromeUtils.import(
"resource://services-settings/remote-settings.js"
);
let nsLoginInfo = new Components.Constructor(
"@mozilla.org/login-manager/loginInfo;1",
Ci.nsILoginInfo,
@ -27,14 +34,15 @@ let TEST_LOGIN2 = new nsLoginInfo(
);
let TEST_LOGIN3 = new nsLoginInfo(
"https://breached.com",
"https://breached.com",
"https://breached.example.com",
"https://breached.example.com",
null,
"breachedLogin1",
"pass3",
"breachedLogin",
"password"
);
TEST_LOGIN3.QueryInterface(Ci.nsILoginMetaInfo).timePasswordChanged = 123456;
async function addLogin(login) {
let storageChangedPromised = TestUtils.topicObserved(
@ -55,3 +63,25 @@ async function addLogin(login) {
});
return login;
}
let EXPECTED_BREACH = null;
add_task(async function setup() {
const collection = await RemoteSettings(
LoginBreaches.REMOTE_SETTINGS_COLLECTION
).openCollection();
if (EXPECTED_BREACH) {
await collection.create(EXPECTED_BREACH, {
useRecordId: true,
});
}
await collection.db.saveLastModified(42);
if (EXPECTED_BREACH) {
await RemoteSettings(LoginBreaches.REMOTE_SETTINGS_COLLECTION).emit(
"sync",
{ data: { current: [EXPECTED_BREACH] } }
);
}
registerCleanupFunction(async () => {
await collection.clear();
});
});

Просмотреть файл

@ -139,7 +139,7 @@ add_task(async function test_set_login() {
add_task(async function test_update_breaches() {
gLoginItem.setLogin(TEST_LOGIN_1);
gLoginItem.updateBreaches(TEST_BREACHES_MAP);
gLoginItem.setBreaches(TEST_BREACHES_MAP);
await asyncElementRendered();
let correspondingBreach = TEST_BREACHES_MAP.get(gLoginItem._login.guid);
@ -150,7 +150,7 @@ add_task(async function test_update_breaches() {
add_task(async function test_breach_alert_is_correctly_hidden() {
gLoginItem.setLogin(TEST_LOGIN_2);
gLoginItem.updateBreaches(TEST_BREACHES_MAP);
gLoginItem.setBreaches(TEST_BREACHES_MAP);
await asyncElementRendered();
let breachAlert = gLoginItem.shadowRoot.querySelector(".breach-alert");

Просмотреть файл

@ -242,7 +242,7 @@ add_task(async function test_populated_list() {
});
add_task(async function test_breach_indicator() {
gLoginList.updateBreaches(TEST_BREACHES_MAP);
gLoginList.setBreaches(TEST_BREACHES_MAP);
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
let warningIcon = loginListItems[0].querySelector(".list-item-warning-icon");
let hiddenWarningIcon = loginListItems[1].querySelector(".list-item-warning-icon");
@ -459,7 +459,7 @@ add_task(async function test_sorted_list() {
is(pwChanged2 > pwChanged3, true, "Logins sorted by timePasswordChanged. Second: " + pwChanged2 + "; Third: " + pwChanged3);
// sort by breached when there are breached logins
gLoginList.updateBreaches(TEST_BREACHES_MAP);
gLoginList.setBreaches(TEST_BREACHES_MAP);
loginSort.selectedIndex = 3;
dispatchChangeEvent(loginSort);
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
@ -467,7 +467,7 @@ add_task(async function test_sorted_list() {
is(!loginListItems[1].classList.contains("breached"), true, "Non-breached login should be displayed below breached");
// sort by name when there are no breached logins
gLoginList.updateBreaches(new Map());
gLoginList.setBreaches(new Map());
loginSort.selectedIndex = 3;
dispatchChangeEvent(loginSort);
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");

Просмотреть файл

@ -240,7 +240,7 @@ add_task(async function test_ExceptionsThrownByNonStandardURIsAreCaught() {
);
});
add_task(async function test_updateBreachesFromRemoteSettingsSync() {
add_task(async function test_setBreachesFromRemoteSettingsSync() {
const login = NOT_BREACHED_SUBDOMAIN_LOGIN;
const nowExampleIsInBreachedRecords = [
{

Просмотреть файл

@ -169,6 +169,10 @@ this.DownloadsViewUI.DownloadElementShell.prototype = {
connect() {
let document = this.element.ownerDocument;
let downloadListItemFragment = gDownloadListItemFragments.get(document);
// When changing the markup within the fragment, please ensure that
// the functions within DownloadsView still operate correctly.
// E.g. onDownloadClick() relies on brittle logic and performs/prevents
// actions based on the check if originaltarget was not a button.
if (!downloadListItemFragment) {
let MozXULElement = document.defaultView.MozXULElement;
downloadListItemFragment = MozXULElement.parseXULToFragment(`

Просмотреть файл

@ -814,10 +814,7 @@ var DownloadsView = {
onDownloadClick(aEvent) {
// Handle primary clicks only, and exclude the action button.
if (
aEvent.button == 0 &&
!aEvent.originalTarget.hasAttribute("oncommand")
) {
if (aEvent.button == 0 && aEvent.originalTarget.localName != "button") {
let target = aEvent.target;
while (target.nodeName != "richlistitem") {
target = target.parentNode;

Просмотреть файл

@ -18,12 +18,6 @@ login-filter =
create-login-button = Create New Login
# This string is used as alternative text for favicon images.
# Variables:
# $title (String) - The title of the website associated with the favicon.
login-favicon =
.alt = Favicon for { $title }
fxaccounts-sign-in-text = Get your passwords on your other devices
fxaccounts-sign-in-button = Sign in to { -sync-brand-short-name }
fxaccounts-avatar-button =
@ -65,8 +59,7 @@ about-logins-login-list-empty-search-description = There are no results matching
login-list-item-title-new-login = New Login
login-list-item-subtitle-new-login = Enter your login credentials
login-list-item-subtitle-missing-username = (no username)
about-logins-list-item-warning-icon =
.alt = Warning icon
about-logins-list-item-breach-icon =
.title = Breached website
## Introduction screen
@ -151,7 +144,7 @@ breach-alert-dismiss =
# a new login that is identical to an existing saved login.
# Variables:
# $loginTitle (String) - The title of the website associated with the login.
about-logins-error-message-duplicate-login = An entry for { $loginTitle } with that username already exists.
about-logins-error-message-duplicate-login-with-link = An entry for { $loginTitle } with that username already exists. <a data-l10n-name="duplicate-link">Go to existing entry?</a>
# This is a generic error message.
about-logins-error-message-default = An error occurred while trying to save this password.

Просмотреть файл

@ -173,11 +173,18 @@ class Message extends Component {
}
onContextMenu(e) {
const { serviceContainer, source, request, messageId } = this.props;
const {
serviceContainer,
source,
request,
messageId,
executionPoint,
} = this.props;
const messageInfo = {
source,
request,
messageId,
executionPoint,
};
serviceContainer.openContextMenu(e, messageInfo);
e.stopPropagation();

Просмотреть файл

@ -377,6 +377,7 @@ skip-if = fission
[browser_webconsole_keyboard_accessibility.js]
[browser_webconsole_location_debugger_link.js]
[browser_webconsole_location_logpoint_debugger_link.js]
skip-if = (os == 'linux' && bits == 64) || (os == 'win') # Bug 1583706
[browser_webconsole_location_scratchpad_link.js]
[browser_webconsole_location_styleeditor_link.js]
[browser_webconsole_logErrorInPage.js]

Просмотреть файл

@ -34,7 +34,7 @@ add_task(async function test() {
front.destroy();
await Assert.rejects(
front.getDescription(),
/Can not send request because front 'device' is already destroyed\./,
/Can not send request 'getDescription' because front 'device' is already destroyed\./,
"Check device front throws when getDescription() is called after destroy()"
);

Просмотреть файл

@ -27,7 +27,7 @@ var generateRequestMethods = function(actorSpec, frontProto) {
// The front was probably destroyed earlier.
if (!this.actorID) {
throw new Error(
`Can not send request because front '${
`Can not send request '${name}' because front '${
this.typeName
}' is already destroyed.`
);

Просмотреть файл

@ -12,7 +12,7 @@ load 500328-1.html
load 514779-1.xhtml
load 614499-1.html
load 678872-1.html
pref(dom.disable_open_during_load,false) load 914521.html
skip-if(Android) pref(dom.disable_open_during_load,false) load 914521.html # Android bug 1584562
pref(browser.send_pings,true) load 1257730-1.html
load 1331295.html
load 1341657.html

Просмотреть файл

@ -85,7 +85,7 @@ skip-if(verify&&isDebugBuild&&gtkWidget) load 1157994.html
load 1158427.html
skip-if(verify&&isDebugBuild&&gtkWidget) load 1185176.html
load 1185192.html
load 1257700.html
skip-if(Android) load 1257700.html # bug 1575666
load 1267263.html
load 1270303.html
load 1304948.html

Просмотреть файл

@ -246,12 +246,11 @@ var sdputils = {
return answer_sdp;
}
ok(
offer_sdp.includes("a=simulcast: send rid"),
offer_sdp.includes("a=simulcast:send "),
"Offer contains simulcast attribute"
);
var o_simul = offer_sdp.match(/simulcast: send rid=(.*)([\n$])*/i);
var new_answer_sdp =
answer_sdp + "a=simulcast: recv rid=" + o_simul[1] + "\r\n";
var o_simul = offer_sdp.match(/simulcast:send (.*)([\n$])*/i);
var new_answer_sdp = answer_sdp + "a=simulcast:recv " + o_simul[1] + "\r\n";
ok(offer_sdp.includes("a=rid:"), "Offer contains RID attribute");
var o_rids = offer_sdp.match(/a=rid:(.*)/gi);
o_rids.forEach(o_rid => {

Просмотреть файл

@ -34,8 +34,3 @@ html|input.num {
#linux html|input.num {
padding-inline-end: 3px;
}
html|div.plainfield {
color: -moz-fieldtext;
white-space: pre;
}

Просмотреть файл

@ -1,12 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="Textbox tests">
<script type="text/javascript" src="platform.js"/>
<textbox value=" test" class="plain"/>
</window>

Просмотреть файл

@ -1,13 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="Textbox tests">
<script type="text/javascript" src="platform.js"/>
<html:div class="plainfield"> test</html:div>
</window>

Просмотреть файл

@ -6,7 +6,6 @@ fails-if(Android) skip-if(winWidget) == chrome://reftest/content/editor/reftests
fails-if(Android) skip-if(winWidget) == chrome://reftest/content/editor/reftests/xul/passwd-1.xul chrome://reftest/content/editor/reftests/xul/passwd-ref.xul # Windows: bug 1239170
fails-if(Android) skip-if(winWidget) == chrome://reftest/content/editor/reftests/xul/passwd-2.xul chrome://reftest/content/editor/reftests/xul/passwd-ref.xul # Windows: bug 1239170
!= chrome://reftest/content/editor/reftests/xul/passwd-3.xul chrome://reftest/content/editor/reftests/xul/passwd-ref.xul
fails-if(Android) == chrome://reftest/content/editor/reftests/xul/plain-1.xul chrome://reftest/content/editor/reftests/xul/plain-ref.xul # bug 783658
fails-if(Android) skip-if(winWidget) == chrome://reftest/content/editor/reftests/xul/textbox-1.xul chrome://reftest/content/editor/reftests/xul/textbox-ref.xul # Windows: bug 1239170
!= chrome://reftest/content/editor/reftests/xul/textbox-disabled.xul chrome://reftest/content/editor/reftests/xul/textbox-ref.xul
# Read-only textboxes look like normal textboxes in windows Vista/7 default theme

Просмотреть файл

@ -526,46 +526,25 @@ struct DIGroup {
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
InvalidateRect(aData->mRect);
GP("DetectContainerLayerPropertiesBoundsChange change\n");
} else if (!aData->mImageRect.IsEqualEdges(mClippedImageBounds)) {
// Make sure we update mRect for mClippedImageBounds changes
nsRect clippedBounds = clip.ApplyNonRoundedIntersection(
geometry->ComputeInvalidationRegion());
IntRect transformedRect =
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel);
// The invalid rect should contain the old rect and the new rect
// but may not because the parent may have been removed.
InvalidateRect(aData->mRect);
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
InvalidateRect(aData->mRect);
GP("ContainerLayer image rect bounds change\n");
} else {
// XXX: this code can eventually be deleted/made debug only
// Handle changes in mClippedImageBounds
nsRect clippedBounds = clip.ApplyNonRoundedIntersection(
geometry->ComputeInvalidationRegion());
IntRect transformedRect =
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel);
auto rect = transformedRect.Intersect(mClippedImageBounds);
GP("Layer NoChange: %s %d %d %d %d\n", aItem->Name(),
if (!rect.IsEqualEdges(aData->mRect)) {
GP("ContainerLayer image rect bounds change\n");
InvalidateRect(aData->mRect);
aData->mRect = rect;
InvalidateRect(aData->mRect);
} else {
GP("Layer NoChange: %s %d %d %d %d\n", aItem->Name(),
aData->mRect.x, aData->mRect.y, aData->mRect.XMost(),
aData->mRect.YMost());
MOZ_RELEASE_ASSERT(rect.IsEqualEdges(aData->mRect));
}
}
} else if (!aData->mImageRect.IsEqualEdges(mClippedImageBounds)) {
// Make sure we update mRect for mClippedImageBounds changes
UniquePtr<nsDisplayItemGeometry> geometry(
aItem->AllocateGeometry(aBuilder));
nsRect clippedBounds = clip.ApplyNonRoundedIntersection(
geometry->ComputeInvalidationRegion());
IntRect transformedRect =
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel);
// The invalid rect should contain the old rect and the new rect
// but may not because the parent may have been removed.
InvalidateRect(aData->mRect);
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
InvalidateRect(aData->mRect);
GP("image rect bounds change\n");
} else {
// XXX: this code can eventually be deleted/made debug only
UniquePtr<nsDisplayItemGeometry> geometry(
aItem->AllocateGeometry(aBuilder));
nsRect clippedBounds = clip.ApplyNonRoundedIntersection(
@ -573,10 +552,17 @@ struct DIGroup {
IntRect transformedRect =
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel);
auto rect = transformedRect.Intersect(mClippedImageBounds);
GP("NoChange: %s %d %d %d %d vs %d %d %d %d\n", aItem->Name(), rect.x,
rect.y, rect.XMost(), rect.YMost(), aData->mRect.x, aData->mRect.y,
aData->mRect.XMost(), aData->mRect.YMost());
MOZ_RELEASE_ASSERT(rect.IsEqualEdges(aData->mRect));
// Make sure we update mRect for mClippedImageBounds changes
if (!rect.IsEqualEdges(aData->mRect)) {
GP("ContainerLayer image rect bounds change\n");
InvalidateRect(aData->mRect);
aData->mRect = rect;
InvalidateRect(aData->mRect);
} else {
GP("NoChange: %s %d %d %d %d\n", aItem->Name(),
aData->mRect.x, aData->mRect.y, aData->mRect.XMost(),
aData->mRect.YMost());
}
}
}
}

Просмотреть файл

@ -527,6 +527,11 @@ case "$target" in
DSO_CFLAGS=
DSO_PIC_CFLAGS=
if test -n "$GNU_CC" -o -n "$CLANG_CC"; then
# $GNU_CC will match gcc and clang; while $CLANG_CC will match only clang
if test -z "$CLANG_CC"; then
AC_MSG_ERROR(Firefox cannot be built with mingw-gcc and requires a mingw-clang toolchain to work)
fi
CC="$CC -mwindows"
CXX="$CXX -mwindows"
CPP="$CPP -mwindows"
@ -537,13 +542,8 @@ case "$target" in
LIBS="$LIBS -lusp10 -lgdi32 -lwinmm -lwsock32"
MOZ_FIX_LINK_PATHS=
if test -z "$CLANG_CC"; then
# Use static libgcc and libstdc++
LDFLAGS="$LDFLAGS -static"
else
# Silence problematic clang warnings
CXXFLAGS="$CXXFLAGS -Wno-incompatible-ms-struct"
fi
# Silence problematic clang warnings
CXXFLAGS="$CXXFLAGS -Wno-incompatible-ms-struct"
MOZ_OPTIMIZE_FLAGS="-O2"

Просмотреть файл

@ -36,6 +36,7 @@
#if defined(MALLOC_H)
# include MALLOC_H /* for malloc_usable_size, malloc_size, _msize */
#endif
#include <ctime>
#include <math.h>
#include <signal.h>
#include <stdio.h>
@ -2684,6 +2685,13 @@ static bool Now(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
static bool CpuNow(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
double now = double(std::clock()) / double(CLOCKS_PER_SEC);
args.rval().setDouble(now);
return true;
}
static bool PrintInternal(JSContext* cx, const CallArgs& args, RCFile* file) {
if (!file->isOpen()) {
JS_ReportErrorASCII(cx, "output file is closed");
@ -9132,6 +9140,12 @@ JS_FN_HELP("parseBin", BinParse, 1, 0,
" object: Don't create a new DOM object, but instead use the supplied\n"
" FakeDOMObject."),
JS_FN_HELP("cpuNow", CpuNow, /* nargs= */ 0, /* flags = */ 0,
"cpuNow()",
" Returns the approximate processor time used by the process since an arbitrary epoch, in seconds.\n"
" Only the difference between two calls to `cpuNow()` is meaningful."),
JS_FS_HELP_END
};
// clang-format on

Просмотреть файл

@ -46,16 +46,17 @@ nsTArray<nsString> ImportScanner::Stop() {
return std::move(mUrlsFound);
}
void ImportScanner::DoScan(Span<const char16_t> aFragment) {
MOZ_ASSERT(mState != State::OutsideOfStyleElement);
MOZ_ASSERT(mState != State::Done);
nsTArray<nsString> ImportScanner::Scan(Span<const char16_t> aFragment) {
MOZ_ASSERT(ShouldScan());
for (char16_t c : aFragment) {
mState = Scan(c);
if (mState == State::Done) {
return;
break;
}
}
return std::move(mUrlsFound);
}
auto ImportScanner::Scan(char16_t aChar) -> State {

Просмотреть файл

@ -26,14 +26,17 @@ struct ImportScanner final {
// Called when a <style> element ends. Returns the list of URLs scanned.
nsTArray<nsString> Stop();
// Scan() should be called when text content is parsed.
void Scan(Span<const char16_t> aFragment) {
if (mState == State::OutsideOfStyleElement || mState == State::Done) {
return;
}
DoScan(aFragment);
// Whether Scan() should be called.
bool ShouldScan() const {
return mState != State::OutsideOfStyleElement && mState != State::Done;
}
// Scan() should be called when text content is parsed, and returns an array
// of found URLs, if any.
//
// Asserts ShouldScan() returns true.
nsTArray<nsString> Scan(Span<const char16_t> aFragment);
private:
enum class State {
// Initial state, doesn't scan anything until Start() is called.
@ -64,7 +67,6 @@ struct ImportScanner final {
};
void EmitUrl();
void DoScan(Span<const char16_t> aFragment);
MOZ_MUST_USE State Scan(char16_t aChar);
static constexpr const uint32_t kMaxRuleNameLength = 7; // (charset, import)

Просмотреть файл

@ -10,10 +10,12 @@
using namespace mozilla;
static nsTArray<nsString> Scan(const char* aCssCode) {
nsTArray<nsString> urls;
ImportScanner scanner;
scanner.Start();
scanner.Scan(NS_ConvertUTF8toUTF16(aCssCode));
return scanner.Stop();
urls.AppendElements(scanner.Scan(NS_ConvertUTF8toUTF16(aCssCode)));
urls.AppendElements(scanner.Stop());
return urls;
}
TEST(ImportScanner, Simple)

Просмотреть файл

@ -1,5 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window align="start" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<vbox style="-moz-appearance: textfield;" width="100" height="100"/>
</window>

Просмотреть файл

@ -1200,9 +1200,9 @@ TEST_F(JsepTrackTest, SimulcastOfferer) {
ASSERT_EQ(10000U,
mSendOff.GetNegotiatedDetails()->GetEncoding(1).mConstraints.maxBr);
ASSERT_NE(std::string::npos,
mOffer->ToString().find("a=simulcast: send rid=foo;bar"));
mOffer->ToString().find("a=simulcast:send foo;bar"));
ASSERT_NE(std::string::npos,
mAnswer->ToString().find("a=simulcast: recv rid=foo;bar"));
mAnswer->ToString().find("a=simulcast:recv foo;bar"));
ASSERT_NE(std::string::npos, mOffer->ToString().find("a=rid:foo send"));
ASSERT_NE(std::string::npos, mOffer->ToString().find("a=rid:bar send"));
ASSERT_NE(std::string::npos, mAnswer->ToString().find("a=rid:foo recv"));
@ -1229,9 +1229,9 @@ TEST_F(JsepTrackTest, SimulcastAnswerer) {
ASSERT_EQ(10000U,
mSendAns.GetNegotiatedDetails()->GetEncoding(1).mConstraints.maxBr);
ASSERT_NE(std::string::npos,
mOffer->ToString().find("a=simulcast: recv rid=foo;bar"));
mOffer->ToString().find("a=simulcast:recv foo;bar"));
ASSERT_NE(std::string::npos,
mAnswer->ToString().find("a=simulcast: send rid=foo;bar"));
mAnswer->ToString().find("a=simulcast:send foo;bar"));
ASSERT_NE(std::string::npos, mOffer->ToString().find("a=rid:foo recv"));
ASSERT_NE(std::string::npos, mOffer->ToString().find("a=rid:bar recv"));
ASSERT_NE(std::string::npos, mAnswer->ToString().find("a=rid:foo send"));

Просмотреть файл

@ -3292,10 +3292,9 @@ TEST_P(NewSdpTest, CheckSimulcast) {
ASSERT_EQ(2U, simulcast.recvVersions.size());
ASSERT_EQ(0U, simulcast.sendVersions.size());
ASSERT_EQ(1U, simulcast.recvVersions[0].choices.size());
ASSERT_EQ("bar", simulcast.recvVersions[0].choices[0]);
ASSERT_EQ("bar", simulcast.recvVersions[0].choices[0].rid);
ASSERT_EQ(1U, simulcast.recvVersions[1].choices.size());
ASSERT_EQ("bar123", simulcast.recvVersions[1].choices[0]);
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, simulcast.recvVersions.type);
ASSERT_EQ("bar123", simulcast.recvVersions[1].choices[0].rid);
}
TEST_P(NewSdpTest, CheckSctpmap) {
@ -4831,19 +4830,19 @@ TEST(NewSdpTestNoFixture, CheckSimulcastVersionSerialize)
std::ostringstream os;
SdpSimulcastAttribute::Version version;
version.choices.push_back("8");
version.choices.push_back(SdpSimulcastAttribute::Encoding("8", false));
version.Serialize(os);
ASSERT_EQ("8", os.str());
os.str("");
version.choices.push_back("9");
version.choices.push_back(SdpSimulcastAttribute::Encoding("9", true));
version.Serialize(os);
ASSERT_EQ("8,9", os.str());
ASSERT_EQ("8,~9", os.str());
os.str("");
version.choices.push_back("0");
version.choices.push_back(SdpSimulcastAttribute::Encoding("0", false));
version.Serialize(os);
ASSERT_EQ("8,9,0", os.str());
ASSERT_EQ("8,~9,0", os.str());
os.str("");
}
@ -4863,14 +4862,17 @@ TEST(NewSdpTestNoFixture, CheckSimulcastVersionValidParse)
{
SdpSimulcastAttribute::Version version(ParseSimulcastVersion("1"));
ASSERT_EQ(1U, version.choices.size());
ASSERT_EQ("1", version.choices[0]);
ASSERT_EQ("1", version.choices[0].rid);
ASSERT_FALSE(version.choices[0].paused);
}
{
SdpSimulcastAttribute::Version version(ParseSimulcastVersion("1,2"));
SdpSimulcastAttribute::Version version(ParseSimulcastVersion("1,~2"));
ASSERT_EQ(2U, version.choices.size());
ASSERT_EQ("1", version.choices[0]);
ASSERT_EQ("2", version.choices[1]);
ASSERT_EQ("1", version.choices[0].rid);
ASSERT_EQ("2", version.choices[1].rid);
ASSERT_FALSE(version.choices[0].paused);
ASSERT_TRUE(version.choices[1].paused);
}
}
@ -4891,32 +4893,28 @@ TEST(NewSdpTestNoFixture, CheckSimulcastVersionsSerialize)
std::ostringstream os;
SdpSimulcastAttribute::Versions versions;
versions.type = SdpSimulcastAttribute::Versions::kPt;
versions.push_back(SdpSimulcastAttribute::Version());
versions.back().choices.push_back("8");
versions.back().choices.push_back(
SdpSimulcastAttribute::Encoding("8", false));
versions.Serialize(os);
ASSERT_EQ("pt=8", os.str());
os.str("");
versions.type = SdpSimulcastAttribute::Versions::kRid;
versions.Serialize(os);
ASSERT_EQ("rid=8", os.str());
ASSERT_EQ("8", os.str());
os.str("");
versions.push_back(SdpSimulcastAttribute::Version());
versions.Serialize(os);
ASSERT_EQ("rid=8", os.str());
ASSERT_EQ("8", os.str());
os.str("");
versions.back().choices.push_back("9");
versions.back().choices.push_back(SdpSimulcastAttribute::Encoding("9", true));
versions.Serialize(os);
ASSERT_EQ("rid=8;9", os.str());
ASSERT_EQ("8;~9", os.str());
os.str("");
versions.push_back(SdpSimulcastAttribute::Version());
versions.back().choices.push_back("0");
versions.back().choices.push_back(
SdpSimulcastAttribute::Encoding("0", false));
versions.Serialize(os);
ASSERT_EQ("rid=8;9;0", os.str());
ASSERT_EQ("8;~9;0", os.str());
os.str("");
}
@ -4933,67 +4931,35 @@ static SdpSimulcastAttribute::Versions ParseSimulcastVersions(
TEST(NewSdpTestNoFixture, CheckSimulcastVersionsValidParse)
{
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("pt=8"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt, versions.type);
ASSERT_EQ(1U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("rid=8"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, versions.type);
ASSERT_EQ(1U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("8"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, versions.type);
ASSERT_EQ(1U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("8", versions[0].choices[0].rid);
ASSERT_FALSE(versions[0].choices[0].paused);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("pt=8,9"));
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("~8,9"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(2U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("9", versions[0].choices[1]);
ASSERT_EQ("8", versions[0].choices[0].rid);
ASSERT_EQ("9", versions[0].choices[1].rid);
ASSERT_TRUE(versions[0].choices[0].paused);
ASSERT_FALSE(versions[0].choices[1].paused);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("8,9"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, versions.type);
ASSERT_EQ(2U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("9", versions[0].choices[1]);
}
{
SdpSimulcastAttribute::Versions versions(
ParseSimulcastVersions("pt=8,9;10"));
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("8,9;~10"));
ASSERT_EQ(2U, versions.size());
ASSERT_EQ(2U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("9", versions[0].choices[1]);
ASSERT_EQ("8", versions[0].choices[0].rid);
ASSERT_EQ("9", versions[0].choices[1].rid);
ASSERT_FALSE(versions[0].choices[0].paused);
ASSERT_FALSE(versions[0].choices[1].paused);
ASSERT_EQ(1U, versions[1].choices.size());
ASSERT_EQ("10", versions[1].choices[0]);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("8,9;10"));
ASSERT_EQ(2U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, versions.type);
ASSERT_EQ(2U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("9", versions[0].choices[1]);
ASSERT_EQ(1U, versions[1].choices.size());
ASSERT_EQ("10", versions[1].choices[0]);
ASSERT_EQ("10", versions[1].choices[0].rid);
ASSERT_TRUE(versions[1].choices[0].paused);
}
}
@ -5001,14 +4967,8 @@ TEST(NewSdpTestNoFixture, CheckSimulcastVersionsInvalidParse)
{
ParseInvalid<SdpSimulcastAttribute::Versions>("", 0);
ParseInvalid<SdpSimulcastAttribute::Versions>(";", 0);
ParseInvalid<SdpSimulcastAttribute::Versions>("foo=", 4);
ParseInvalid<SdpSimulcastAttribute::Versions>("foo=8", 4);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=9999", 7);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=-1", 5);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=x", 4);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=8;", 5);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=8;x", 6);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=8;;", 5);
ParseInvalid<SdpSimulcastAttribute::Versions>("8;", 2);
ParseInvalid<SdpSimulcastAttribute::Versions>("8;;", 2);
}
TEST(NewSdpTestNoFixture, CheckSimulcastSerialize)
@ -5016,18 +4976,18 @@ TEST(NewSdpTestNoFixture, CheckSimulcastSerialize)
std::ostringstream os;
SdpSimulcastAttribute simulcast;
simulcast.recvVersions.type = SdpSimulcastAttribute::Versions::kRid;
simulcast.recvVersions.push_back(SdpSimulcastAttribute::Version());
simulcast.recvVersions.back().choices.push_back("8");
simulcast.recvVersions.back().choices.push_back(
SdpSimulcastAttribute::Encoding("8", false));
simulcast.Serialize(os);
ASSERT_EQ("a=simulcast: recv rid=8" CRLF, os.str());
ASSERT_EQ("a=simulcast:recv 8" CRLF, os.str());
os.str("");
simulcast.sendVersions.type = SdpSimulcastAttribute::Versions::kRid;
simulcast.sendVersions.push_back(SdpSimulcastAttribute::Version());
simulcast.sendVersions.back().choices.push_back("9");
simulcast.sendVersions.back().choices.push_back(
SdpSimulcastAttribute::Encoding("9", true));
simulcast.Serialize(os);
ASSERT_EQ("a=simulcast: send rid=9 recv rid=8" CRLF, os.str());
ASSERT_EQ("a=simulcast:send ~9 recv 8" CRLF, os.str());
}
static SdpSimulcastAttribute ParseSimulcast(const std::string& input) {
@ -5044,90 +5004,54 @@ TEST(NewSdpTestNoFixture, CheckSimulcastValidParse)
{
SdpSimulcastAttribute simulcast(ParseSimulcast("send 8"));
ASSERT_EQ(1U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid,
simulcast.sendVersions.type);
ASSERT_EQ(1U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0].rid);
ASSERT_FALSE(simulcast.sendVersions[0].choices[0].paused);
ASSERT_EQ(0U, simulcast.recvVersions.size());
}
{
SdpSimulcastAttribute simulcast(ParseSimulcast(" send pt=8"));
SdpSimulcastAttribute simulcast(ParseSimulcast(" SEND 8"));
ASSERT_EQ(1U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.sendVersions.type);
ASSERT_EQ(1U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0].rid);
ASSERT_FALSE(simulcast.sendVersions[0].choices[0].paused);
ASSERT_EQ(0U, simulcast.recvVersions.size());
}
{
SdpSimulcastAttribute simulcast(ParseSimulcast(" SEND pt=8"));
ASSERT_EQ(1U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.sendVersions.type);
ASSERT_EQ(1U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ(0U, simulcast.recvVersions.size());
}
{
SdpSimulcastAttribute simulcast(ParseSimulcast(" recv pt=8"));
SdpSimulcastAttribute simulcast(ParseSimulcast("recv 8"));
ASSERT_EQ(1U, simulcast.recvVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.recvVersions.type);
ASSERT_EQ(1U, simulcast.recvVersions[0].choices.size());
ASSERT_EQ("8", simulcast.recvVersions[0].choices[0]);
ASSERT_EQ("8", simulcast.recvVersions[0].choices[0].rid);
ASSERT_FALSE(simulcast.recvVersions[0].choices[0].paused);
ASSERT_EQ(0U, simulcast.sendVersions.size());
}
{
SdpSimulcastAttribute simulcast(
ParseSimulcast("send 8,9;101;97,98 recv 101,120;97"));
ParseSimulcast("send 8,9;~101;97,~98 recv 101,120;97"));
ASSERT_EQ(3U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid,
simulcast.sendVersions.type);
ASSERT_EQ(2U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ("9", simulcast.sendVersions[0].choices[1]);
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0].rid);
ASSERT_EQ("9", simulcast.sendVersions[0].choices[1].rid);
ASSERT_FALSE(simulcast.sendVersions[0].choices[0].paused);
ASSERT_FALSE(simulcast.sendVersions[0].choices[1].paused);
ASSERT_EQ(1U, simulcast.sendVersions[1].choices.size());
ASSERT_EQ("101", simulcast.sendVersions[1].choices[0]);
ASSERT_EQ("101", simulcast.sendVersions[1].choices[0].rid);
ASSERT_TRUE(simulcast.sendVersions[1].choices[0].paused);
ASSERT_EQ(2U, simulcast.sendVersions[2].choices.size());
ASSERT_EQ("97", simulcast.sendVersions[2].choices[0]);
ASSERT_EQ("98", simulcast.sendVersions[2].choices[1]);
ASSERT_EQ("97", simulcast.sendVersions[2].choices[0].rid);
ASSERT_EQ("98", simulcast.sendVersions[2].choices[1].rid);
ASSERT_FALSE(simulcast.sendVersions[2].choices[0].paused);
ASSERT_TRUE(simulcast.sendVersions[2].choices[1].paused);
ASSERT_EQ(2U, simulcast.recvVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid,
simulcast.recvVersions.type);
ASSERT_EQ(2U, simulcast.recvVersions[0].choices.size());
ASSERT_EQ("101", simulcast.recvVersions[0].choices[0]);
ASSERT_EQ("120", simulcast.recvVersions[0].choices[1]);
ASSERT_EQ("101", simulcast.recvVersions[0].choices[0].rid);
ASSERT_EQ("120", simulcast.recvVersions[0].choices[1].rid);
ASSERT_EQ(1U, simulcast.recvVersions[1].choices.size());
ASSERT_EQ("97", simulcast.recvVersions[1].choices[0]);
}
{
SdpSimulcastAttribute simulcast(
ParseSimulcast(" send pt=8,9;101;97,98 recv pt=101,120;97"));
ASSERT_EQ(3U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.sendVersions.type);
ASSERT_EQ(2U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ("9", simulcast.sendVersions[0].choices[1]);
ASSERT_EQ(1U, simulcast.sendVersions[1].choices.size());
ASSERT_EQ("101", simulcast.sendVersions[1].choices[0]);
ASSERT_EQ(2U, simulcast.sendVersions[2].choices.size());
ASSERT_EQ("97", simulcast.sendVersions[2].choices[0]);
ASSERT_EQ("98", simulcast.sendVersions[2].choices[1]);
ASSERT_EQ(2U, simulcast.recvVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.recvVersions.type);
ASSERT_EQ(2U, simulcast.recvVersions[0].choices.size());
ASSERT_EQ("101", simulcast.recvVersions[0].choices[0]);
ASSERT_EQ("120", simulcast.recvVersions[0].choices[1]);
ASSERT_EQ(1U, simulcast.recvVersions[1].choices.size());
ASSERT_EQ("97", simulcast.recvVersions[1].choices[0]);
ASSERT_EQ("97", simulcast.recvVersions[1].choices[0].rid);
}
}
@ -5136,8 +5060,8 @@ TEST(NewSdpTestNoFixture, CheckSimulcastInvalidParse)
ParseInvalid<SdpSimulcastAttribute>("", 0);
ParseInvalid<SdpSimulcastAttribute>(" ", 1);
ParseInvalid<SdpSimulcastAttribute>("vcer ", 4);
ParseInvalid<SdpSimulcastAttribute>(" send pt=8 send ", 15);
ParseInvalid<SdpSimulcastAttribute>(" recv pt=8 recv ", 15);
ParseInvalid<SdpSimulcastAttribute>(" send 8 send ", 12);
ParseInvalid<SdpSimulcastAttribute>(" recv 8 recv ", 12);
}
static SdpRidAttributeList::Rid ParseRid(const std::string& input) {

Просмотреть файл

@ -136,7 +136,7 @@ void JsepTrack::AddToAnswer(const SdpMediaSection& offer,
std::vector<JsConstraints> constraints;
if (answer->IsSending()) {
constraints = mJsEncodeConstraints;
std::vector<SdpRidAttributeList::Rid> rids;
std::vector<std::pair<SdpRidAttributeList::Rid, bool>> rids;
GetRids(offer, sdp::kRecv, &rids);
NegotiateRids(rids, &constraints);
}
@ -192,14 +192,15 @@ void JsepTrack::AddToMsection(
// Updates the |id| values in |constraintsList| with the rid values in |rids|,
// where necessary.
void JsepTrack::NegotiateRids(
const std::vector<SdpRidAttributeList::Rid>& rids,
const std::vector<std::pair<SdpRidAttributeList::Rid, bool>>& rids,
std::vector<JsConstraints>* constraintsList) const {
for (const SdpRidAttributeList::Rid& rid : rids) {
if (!FindConstraints(rid.id, *constraintsList)) {
for (const auto& ridAndPaused : rids) {
if (!FindConstraints(ridAndPaused.first.id, *constraintsList)) {
// Pair up the first JsConstraints with an empty id, if it exists.
JsConstraints* constraints = FindConstraints("", *constraintsList);
if (constraints) {
constraints->rid = rid.id;
constraints->rid = ridAndPaused.first.id;
constraints->paused = ridAndPaused.second;
}
}
}
@ -239,7 +240,8 @@ void JsepTrack::AddToMsection(const std::vector<JsConstraints>& constraintsList,
rids->mRids.push_back(rid);
SdpSimulcastAttribute::Version version;
version.choices.push_back(constraints.rid);
version.choices.push_back(
SdpSimulcastAttribute::Encoding(constraints.rid, false));
if (direction == sdp::kSend) {
simulcast->sendVersions.push_back(version);
} else {
@ -259,9 +261,9 @@ void JsepTrack::AddToMsection(const std::vector<JsConstraints>& constraintsList,
}
}
void JsepTrack::GetRids(const SdpMediaSection& msection,
sdp::Direction direction,
std::vector<SdpRidAttributeList::Rid>* rids) const {
void JsepTrack::GetRids(
const SdpMediaSection& msection, sdp::Direction direction,
std::vector<std::pair<SdpRidAttributeList::Rid, bool>>* rids) const {
rids->clear();
if (!msection.GetAttributeList().HasAttribute(
SdpAttribute::kSimulcastAttribute)) {
@ -285,15 +287,11 @@ void JsepTrack::GetRids(const SdpMediaSection& msection,
return;
}
if (versions->type != SdpSimulcastAttribute::Versions::kRid) {
// No support for PT-based simulcast, yet.
return;
}
for (const SdpSimulcastAttribute::Version& version : *versions) {
if (!version.choices.empty()) {
// We validate that rids are present (and sane) elsewhere.
rids->push_back(*msection.FindRid(version.choices[0]));
rids->push_back(std::make_pair(*msection.FindRid(version.choices[0].rid),
version.choices[0].paused));
}
}
}
@ -315,13 +313,13 @@ void JsepTrack::CreateEncodings(
negotiatedDetails->mTias = remote.GetBandwidth("TIAS");
// TODO add support for b=AS if TIAS is not set (bug 976521)
std::vector<SdpRidAttributeList::Rid> rids;
std::vector<std::pair<SdpRidAttributeList::Rid, bool>> rids;
GetRids(remote, sdp::kRecv, &rids); // Get rids we will send
NegotiateRids(rids, &mJsEncodeConstraints);
if (rids.empty()) {
// Add dummy value with an empty id to make sure we get a single unicast
// stream.
rids.push_back(SdpRidAttributeList::Rid());
rids.push_back(std::make_pair(SdpRidAttributeList::Rid(), false));
}
size_t max_streams = 1;
@ -345,17 +343,18 @@ void JsepTrack::CreateEncodings(
auto& encoding = negotiatedDetails->mEncodings[i];
for (const auto& codec : negotiatedCodecs) {
if (rids[i].HasFormat(codec->mDefaultPt)) {
if (rids[i].first.HasFormat(codec->mDefaultPt)) {
encoding->AddCodec(*codec);
}
}
encoding->mRid = rids[i].id;
encoding->mRid = rids[i].first.id;
encoding->mPaused = rids[i].second;
// If we end up supporting params for rid, we would handle that here.
// Incorporate the corresponding JS encoding constraints, if they exist
for (const JsConstraints& jsConstraints : mJsEncodeConstraints) {
if (jsConstraints.rid == rids[i].id) {
if (jsConstraints.rid == rids[i].first.id) {
encoding->mConstraints = jsConstraints.constraints;
}
}

Просмотреть файл

@ -216,9 +216,11 @@ class JsepTrack {
struct JsConstraints {
std::string rid;
bool paused = false;
EncodingConstraints constraints;
bool operator==(const JsConstraints& other) const {
return rid == other.rid && constraints == other.constraints;
return rid == other.rid && paused == other.paused &&
constraints == other.constraints;
}
};
@ -243,8 +245,9 @@ class JsepTrack {
std::vector<uint16_t>* pts);
void AddToMsection(const std::vector<UniquePtr<JsepCodecDescription>>& codecs,
SdpMediaSection* msection);
void GetRids(const SdpMediaSection& msection, sdp::Direction direction,
std::vector<SdpRidAttributeList::Rid>* rids) const;
void GetRids(
const SdpMediaSection& msection, sdp::Direction direction,
std::vector<std::pair<SdpRidAttributeList::Rid, bool>>* rids) const;
void CreateEncodings(
const SdpMediaSection& remote,
const std::vector<UniquePtr<JsepCodecDescription>>& negotiatedCodecs,
@ -256,8 +259,9 @@ class JsepTrack {
JsConstraints* FindConstraints(
const std::string& rid,
std::vector<JsConstraints>& constraintsList) const;
void NegotiateRids(const std::vector<SdpRidAttributeList::Rid>& rids,
std::vector<JsConstraints>* constraints) const;
void NegotiateRids(
const std::vector<std::pair<SdpRidAttributeList::Rid, bool>>& rids,
std::vector<JsConstraints>* constraints) const;
void UpdateSsrcs(SsrcGenerator& ssrcGenerator, size_t encodings);
mozilla::SdpMediaSection::MediaType mType;

Просмотреть файл

@ -46,6 +46,7 @@ class JsepTrackEncoding {
EncodingConstraints mConstraints;
std::string mRid;
bool mPaused = false;
private:
std::vector<UniquePtr<JsepCodecDescription>> mCodecs;

Просмотреть файл

@ -892,7 +892,6 @@ SdpSimulcastAttribute::Versions LoadSimulcastVersions(
rustVersionArray.get());
SdpSimulcastAttribute::Versions versions;
versions.type = SdpSimulcastAttribute::Versions::kRid;
for (size_t i = 0; i < rustVersionCount; i++) {
const RustSdpAttributeSimulcastVersion& rustVersion = rustVersionArray[i];
@ -909,7 +908,8 @@ SdpSimulcastAttribute::Versions LoadSimulcastVersions(
const RustSdpAttributeSimulcastId& rustId = rustIdArray[j];
std::string id = convertStringView(rustId.id);
// TODO: Bug 1225877. Added support for 'paused'-state
version.choices.push_back(id);
version.choices.push_back(
SdpSimulcastAttribute::Encoding(id, rustId.paused));
}
versions.push_back(version);

Просмотреть файл

@ -1076,47 +1076,31 @@ void SdpSetupAttribute::Serialize(std::ostream& os) const {
void SdpSimulcastAttribute::Version::Serialize(std::ostream& os) const {
SkipFirstDelimiter comma(",");
for (const std::string& choice : choices) {
os << comma << choice;
for (const Encoding& choice : choices) {
os << comma;
if (choice.paused) {
os << '~';
}
os << choice.rid;
}
}
bool SdpSimulcastAttribute::Version::Parse(std::istream& is,
std::string* error) {
do {
bool paused = SkipChar(is, '~', error);
std::string value = ParseToken(is, ",; ", error);
if (value.empty()) {
*error = "Missing rid";
return false;
}
choices.push_back(value);
choices.push_back(Encoding(value, paused));
} while (SkipChar(is, ',', error));
return true;
}
bool SdpSimulcastAttribute::Version::GetChoicesAsFormats(
std::vector<uint16_t>* formats) const {
for (const std::string& choice : choices) {
uint16_t format;
if (!SdpHelper::GetPtAsInt(choice, &format) || (format > 127)) {
return false;
}
formats->push_back(format);
}
return true;
}
void SdpSimulcastAttribute::Versions::Serialize(std::ostream& os) const {
switch (type) {
case kRid:
os << "rid=";
break;
case kPt:
os << "pt=";
break;
}
SkipFirstDelimiter semic(";");
for (const Version& version : *this) {
if (!version.IsSet()) {
@ -1129,39 +1113,11 @@ void SdpSimulcastAttribute::Versions::Serialize(std::ostream& os) const {
bool SdpSimulcastAttribute::Versions::Parse(std::istream& is,
std::string* error) {
int startPos = is.tellg();
std::string rawType = ParseKey(is, error);
if (rawType.empty()) {
// New simulcast format does not have pt= or rid=, it is always rid
rawType = "rid";
is.clear();
is.seekg(startPos);
}
if (rawType == "pt") {
type = kPt;
} else if (rawType == "rid") {
type = kRid;
} else {
*error = "Unknown simulcast identification type ";
error->append(rawType);
return false;
}
do {
Version version;
if (!version.Parse(is, error)) {
return false;
}
if (type == kPt) {
std::vector<uint16_t> formats;
if (!version.GetChoicesAsFormats(&formats)) {
*error = "Invalid payload type";
return false;
}
}
push_back(version);
} while (SkipChar(is, ';', error));
@ -1174,12 +1130,15 @@ void SdpSimulcastAttribute::Serialize(std::ostream& os) const {
os << "a=" << mType << ":";
if (sendVersions.IsSet()) {
os << " send ";
os << "send ";
sendVersions.Serialize(os);
}
if (recvVersions.IsSet()) {
os << " recv ";
if (sendVersions.IsSet()) {
os << " ";
}
os << "recv ";
recvVersions.Serialize(os);
}

Просмотреть файл

@ -1535,21 +1535,25 @@ class SdpSimulcastAttribute : public SdpAttribute {
void Serialize(std::ostream& os) const override;
bool Parse(std::istream& is, std::string* error);
class Encoding {
public:
Encoding(const std::string& aRid, bool aPaused)
: rid(aRid), paused(aPaused) {}
std::string rid;
bool paused = false;
};
class Version {
public:
void Serialize(std::ostream& os) const;
bool IsSet() const { return !choices.empty(); }
bool Parse(std::istream& is, std::string* error);
bool GetChoicesAsFormats(std::vector<uint16_t>* formats) const;
std::vector<std::string> choices;
std::vector<Encoding> choices;
};
class Versions : public std::vector<Version> {
public:
enum Type { kPt, kRid };
Versions() : type(kRid) {}
void Serialize(std::ostream& os) const;
bool IsSet() const {
if (empty()) {
@ -1566,7 +1570,6 @@ class SdpSimulcastAttribute : public SdpAttribute {
}
bool Parse(std::istream& is, std::string* error);
Type type;
};
Versions sendVersions;

Просмотреть файл

@ -234,24 +234,14 @@ bool SipccSdpMediaSection::ValidateSimulcastVersions(
}
for (const SdpSimulcastAttribute::Version& version : versions) {
for (const std::string& id : version.choices) {
if (versions.type == SdpSimulcastAttribute::Versions::kRid) {
const SdpRidAttributeList::Rid* ridAttr = FindRid(id);
if (!ridAttr || (ridAttr->direction != direction)) {
std::ostringstream os;
os << "No rid attribute for \'" << id << "\'";
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
os.str());
return false;
}
} else if (versions.type == SdpSimulcastAttribute::Versions::kPt) {
if (std::find(mFormats.begin(), mFormats.end(), id) == mFormats.end()) {
std::ostringstream os;
os << "No pt for \'" << id << "\'";
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
os.str());
return false;
}
for (const SdpSimulcastAttribute::Encoding& encoding : version.choices) {
const SdpRidAttributeList::Rid* ridAttr = FindRid(encoding.rid);
if (!ridAttr || (ridAttr->direction != direction)) {
std::ostringstream os;
os << "No rid attribute for \'" << encoding.rid << "\'";
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
os.str());
return false;
}
}
}

Просмотреть файл

@ -2302,7 +2302,7 @@ pref("services.settings.security.onecrl.signer", "onecrl.content-signature.mozil
pref("services.settings.security.onecrl.checked", 0);
pref("extensions.abuseReport.enabled", true);
pref("extensions.abuseReport.url", "https://addons.mozilla.org/api/v4/abuse/report/addon/");
pref("extensions.abuseReport.url", "https://services.addons.mozilla.org/api/v4/abuse/report/addon/");
// Blocklist preferences
pref("extensions.blocklist.enabled", true);

Просмотреть файл

@ -658,7 +658,6 @@ nsresult FTPChannelParent::ResumeForDiversion() {
if (mSuspendedForDiversion) {
nsresult rv = ResumeChannelInternalIfPossible();
if (NS_WARN_IF(NS_FAILED(rv))) {
FailDiversion(NS_ERROR_UNEXPECTED);
return rv;
}
mSuspendedForDiversion = false;
@ -667,7 +666,6 @@ nsresult FTPChannelParent::ResumeForDiversion() {
// Delete() will tear down IPDL, but ref from underlying nsFTPChannel will
// keep us alive if there's more data to be delivered to listener.
if (NS_WARN_IF(NS_FAILED(Delete()))) {
FailDiversion(NS_ERROR_UNEXPECTED);
return NS_ERROR_UNEXPECTED;
}
return NS_OK;

Просмотреть файл

@ -645,6 +645,11 @@ case "$target" in
# certain versions of cygwin's makedepend barf on the
# #include <string> vs -I./dist/include/string issue so don't use it
if test -n "$GNU_CC" -o -n "$CLANG_CC"; then
# $GNU_CC will match gcc and clang; while $CLANG_CC will match only clang
if test -z "$CLANG_CC"; then
AC_MSG_ERROR(Firefox cannot be built with mingw-gcc and requires a mingw-clang toolchain to work)
fi
CC="$CC -mwindows"
CXX="$CXX -mwindows"
CPP="$CPP -mwindows"
@ -660,19 +665,8 @@ case "$target" in
WIN32_CONSOLE_EXE_LDFLAGS=-mconsole
WIN32_GUI_EXE_LDFLAGS=-mwindows
if test -z "$CLANG_CC"; then
# Use static libgcc and libstdc++
LDFLAGS="$LDFLAGS -static"
# GCC/binutils can't link to a function if we try to include dllexport function
# in the same library as dllimport caller. To work around it, we build NSPR
# and NSS with -mnop-fun-dllimport flag. The drawback of this solution is that
# function thunks need to be generated for cross-DLL calls.
MOZ_FOLD_LIBS_FLAGS="-mnop-fun-dllimport"
else
# Silence problematic clang warnings
CXXFLAGS="$CXXFLAGS -Wno-incompatible-ms-struct"
fi
# Silence problematic clang warnings
CXXFLAGS="$CXXFLAGS -Wno-incompatible-ms-struct"
else
TARGET_COMPILER_ABI=msvc
RANLIB='echo not_ranlib'

Просмотреть файл

@ -678,7 +678,13 @@ void nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent,
memcpy(bufferCopy.get(), aBuffer, aLength * sizeof(char16_t));
mImportScanner.Scan(MakeSpan(aBuffer, aLength));
if (mImportScanner.ShouldScan()) {
nsTArray<nsString> imports =
mImportScanner.Scan(MakeSpan(aBuffer, aLength));
for (nsString& url : imports) {
mSpeculativeLoadQueue.AppendElement()->InitImportStyle(std::move(url));
}
}
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
if (MOZ_UNLIKELY(!treeOp)) {

Просмотреть файл

@ -0,0 +1,26 @@
# coding=utf8
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
from __future__ import absolute_import
import fluent.syntax.ast as FTL
from fluent.migrate.helpers import transforms_from
from fluent.migrate import COPY_PATTERN
TARGET_FILE = "browser/browser/aboutLogins.ftl"
SOURCE_FILE = TARGET_FILE
def migrate(ctx):
"""Bug 1583428 - Remove unnecessary alt attribute on breach icon, part {index}."""
ctx.add_transforms(
TARGET_FILE,
SOURCE_FILE,
transforms_from(
"""
about-logins-list-item-breach-icon =
.title = {COPY_PATTERN(from_path, "about-logins-list-item-warning-icon.title")}
""",
from_path=SOURCE_FILE),
)

Просмотреть файл

@ -212,8 +212,20 @@ def run(paths, linters, formats, outgoing, workdir, edit,
out = formatter(result)
if out:
output_file = open(path, 'w') if path else sys.stdout
print(out, file=output_file)
fh = open(path, 'w') if path else sys.stdout
if not path and fh.encoding == 'ascii':
# If sys.stdout.encoding is ascii, printing output will fail
# due to the stylish formatter's use of unicode characters.
# Ideally the user should fix their environment by setting
# `LC_ALL=C.UTF-8` or similar. But this is a common enough
# problem that we help them out a little here by manually
# encoding and writing to the stdout buffer directly.
out += '\n'
fh.buffer.write(out.encode('utf-8', errors='replace'))
fh.buffer.flush()
else:
print(out, file=fh)
return result.returncode

Просмотреть файл

@ -3,6 +3,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import subprocess
import sys
from distutils.spawn import find_executable
import mozunit
@ -32,6 +34,17 @@ def run(parser, lintdir, files):
return inner
def test_cli_with_ascii_encoding(run, monkeypatch, capfd):
cmd = [sys.executable, 'runcli.py', '-l=string', '-f=stylish']
env = os.environ.copy()
env['PYTHONPATH'] = os.pathsep.join(sys.path)
env['PYTHONIOENCODING'] = 'ascii'
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
cwd=here, env=env, universal_newlines=True)
out = proc.communicate()[0]
assert 'Traceback' not in out
def test_cli_run_with_fix(run, capfd):
ret = run(['-f', 'json', '--fix', '--linter', 'external'])
out, err = capfd.readouterr()

Просмотреть файл

@ -1137,4 +1137,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1578315844440000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1578575176111000);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -947,8 +947,9 @@ def setup_browsertime(config, tests):
'android.*': ['browsertime', 'linux64-geckodriver', 'linux64-node'],
'linux.*': ['browsertime', 'linux64-geckodriver', 'linux64-node'],
'macosx.*': ['browsertime', 'macosx64-geckodriver', 'macosx64-node'],
'windows.*32.*': ['browsertime', 'win32-geckodriver', 'win32-node'],
'windows.*64.*': ['browsertime', 'win64-geckodriver', 'win64-node'],
'windows.*aarch64.*': ['browsertime', 'win32-geckodriver', 'win32-node'],
'windows.*-32.*': ['browsertime', 'win32-geckodriver', 'win32-node'],
'windows.*-64.*': ['browsertime', 'win64-geckodriver', 'win64-node'],
},
}
@ -960,8 +961,9 @@ def setup_browsertime(config, tests):
'android.*': ['linux64-chromedriver', 'linux64-ffmpeg-4.1.4'],
'linux.*': ['linux64-chromedriver', 'linux64-ffmpeg-4.1.4'],
'macosx.*': ['mac64-chromedriver', 'mac64-ffmpeg-4.1.1'],
'windows.*32.*': ['win32-chromedriver', 'win64-ffmpeg-4.1.1'],
'windows.*64.*': ['win32-chromedriver', 'win64-ffmpeg-4.1.1'],
'windows.*aarch64.*': ['win32-chromedriver', 'win64-ffmpeg-4.1.1'],
'windows.*-32.*': ['win32-chromedriver', 'win64-ffmpeg-4.1.1'],
'windows.*-64.*': ['win32-chromedriver', 'win64-ffmpeg-4.1.1'],
},
}

Просмотреть файл

@ -721,7 +721,9 @@ falling back to not using job objects for managing child processes""", file=sys.
self.keywordargs = kwargs
self.read_buffer = ''
if env is None:
# XXX Bug 1585702 - Setting env is broken on Windows + Python 3. In the
# meantime let's at least make sure we don't set it in the default case.
if env is None and not (six.PY3 and isWin):
env = os.environ.copy()
self.env = env

Просмотреть файл

@ -6,11 +6,7 @@
var EXPORTED_SYMBOLS = ["PurgeSessionHistoryChild"];
const { ActorChild } = ChromeUtils.import(
"resource://gre/modules/ActorChild.jsm"
);
class PurgeSessionHistoryChild extends ActorChild {
class PurgeSessionHistoryChild extends JSWindowActorChild {
receiveMessage(message) {
if (message.name != "Browser:PurgeSessionHistory") {
return;
@ -30,7 +26,7 @@ class PurgeSessionHistoryChild extends ActorChild {
}
let purge = sessionHistory.count;
if (this.content.location.href != "about:blank") {
if (this.document.location.href != "about:blank") {
--purge; // Don't remove the page the user's staring at from shistory
}

Просмотреть файл

@ -106,18 +106,11 @@ decorate_task(
{ enrollmentId: rollouts[0].enrollmentId },
],
]);
Assert.deepEqual(
setExperimentActiveStub.args,
[
[
"test-rollout",
"active",
{
type: "normandy-prefrollout",
enrollmentId: rollouts[0].enrollmentId,
},
],
],
ok(
setExperimentActiveStub.calledWithExactly("test-rollout", "active", {
type: "normandy-prefrollout",
enrollmentId: rollouts[0].enrollmentId,
}),
"a telemetry experiment should be activated"
);

Просмотреть файл

@ -1103,6 +1103,18 @@ this.LoginHelper = {
throw e;
}
},
createLoginAlreadyExistsError(guid) {
// The GUID is stored in an nsISupportsString here because we cannot pass
// raw JS objects within Components.Exception due to bug 743121.
let guidSupportsString = Cc[
"@mozilla.org/supports-string;1"
].createInstance(Ci.nsISupportsString);
guidSupportsString.data = guid;
return Components.Exception("This login already exists.", {
data: guidSupportsString,
});
},
};
LoginHelper.init();

Просмотреть файл

@ -312,8 +312,9 @@ LoginManager.prototype = {
login.httpRealm
);
if (logins.some(l => login.matches(l, true))) {
throw new Error("This login already exists.");
let matchingLogin = logins.find(l => login.matches(l, true));
if (matchingLogin) {
throw LoginHelper.createLoginAlreadyExistsError(matchingLogin.guid);
}
log.debug("Adding login");

Просмотреть файл

@ -270,8 +270,9 @@ this.LoginManagerStorage_json.prototype = {
newLogin.httpRealm
);
if (logins.some(login => newLogin.matches(login, true))) {
throw new Error("This login already exists.");
let matchingLogin = logins.find(login => newLogin.matches(login, true));
if (matchingLogin) {
throw LoginHelper.createLoginAlreadyExistsError(matchingLogin.guid);
}
}

Просмотреть файл

@ -367,8 +367,9 @@ LoginManagerStorage_mozStorage.prototype = {
newLogin.httpRealm
);
if (logins.some(login => newLogin.matches(login, true))) {
throw new Error("This login already exists.");
let matchingLogin = logins.find(login => newLogin.matches(login, true));
if (matchingLogin) {
throw LoginHelper.createLoginAlreadyExistsError(matchingLogin.guid);
}
}

Просмотреть файл

@ -544,6 +544,7 @@ this.LoginTestUtils.telemetry = {
}
events = events.filter(e => e[1] == category);
dump(`Waiting for ${count} events, got ${events.length}\n`);
return events.length == count ? events : null;
}, "waiting for telemetry event count of: " + count);
Assert.equal(events.length, count, "waiting for telemetry event count");

Просмотреть файл

@ -145,6 +145,7 @@ skip-if = toolkit == 'android' # Tests desktop prompts
support-files = subtst_prompt_async.html
[test_prompt_http.html]
skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
fail-if = fission # Bug 1585531
[test_prompt_noWindow.html]
skip-if = e10s || toolkit == 'android' # Tests desktop prompts. e10s: bug 1217876
[test_password_length.html]

Просмотреть файл

@ -57,15 +57,17 @@ class SearchEngineSelector {
log(`fetchEngineConfiguration ${region}:${locale}`);
let cohort = Services.prefs.getCharPref("browser.search.cohort", null);
let engines = [];
const lcLocale = locale.toLowerCase();
const lcRegion = region.toLowerCase();
for (let config of this.configuration) {
const appliesTo = config.appliesTo || [];
const applies = appliesTo.filter(section => {
let included =
"included" in section &&
this._isInSection(region, locale, section.included);
this._isInSection(lcRegion, lcLocale, section.included);
let excluded =
"excluded" in section &&
this._isInSection(region, locale, section.excluded);
this._isInSection(lcRegion, lcLocale, section.excluded);
if ("cohort" in section && cohort != section.cohort) {
return false;
}
@ -242,8 +244,12 @@ class SearchEngineSelector {
return true;
}
let locales = config.locales || {};
let inLocales = locales.matches && locales.matches.includes(locale);
let inRegions = config.regions && config.regions.includes(region);
let inLocales =
"matches" in locales &&
!!locales.matches.find(e => e.toLowerCase() == locale);
let inRegions =
"regions" in config &&
!!config.regions.find(e => e.toLowerCase() == region);
if (
locales.startsWith &&
locales.startsWith.some(key => locale.startsWith(key))

Просмотреть файл

@ -4,6 +4,7 @@
"engineName": "Test search engine",
"webExtensionId": "engine@search.mozilla.org",
"webExtensionVersion": "1.0",
"orderHint": 10000,
"appliesTo": [{
"included": { "everywhere": true },
"default": "yes"
@ -13,45 +14,61 @@
"engineName": "engine-pref",
"webExtensionId": "engine-pref@search.mozilla.org",
"webExtensionVersion": "1.0",
"orderHint": 7000,
"appliesTo": [{
"included": { "everywhere": true },
"default": "yes"
"excluded": { "locales": { "matches": ["de"] } },
"default": "no",
"defaultPrivate": "yes"
}]
},
{
"engineName": "engine-rel-searchform-purpose",
"webExtensionId": "engine-rel-searchform-purpose@search.mozilla.org",
"webExtensionVersion": "1.0",
"orderHint": 6000,
"appliesTo": [{
"included": { "everywhere": true },
"default": "yes"
"excluded": { "locales": { "matches": ["de", "fr"] } },
"default": "no"
}]
},
{
"engineName": "engine-chromeicon",
"webExtensionId": "engine-chromeicon@search.mozilla.org",
"webExtensionVersion": "1.0",
"orderHint": 8000,
"appliesTo": [{
"included": { "everywhere": true },
"default": "yes"
"excluded": { "locales": { "matches": ["de", "fr"] } },
"default": "no"
}, {
"included": { "regions": ["ru"] },
"default": "no"
}]
},
{
"engineName": "engine-resourceicon",
"webExtensionId": "engine-resourceicon@search.mozilla.org",
"webExtensionVersion": "1.0",
"orderHint": 9000,
"appliesTo": [{
"included": { "everywhere": true },
"default": "yes"
"included": { "locales": { "matches": ["en-US", "fr"] } },
"excluded": {
"regions": ["ru"]
},
"default": "no"
}]
},
{
"engineName": "engine-reordered",
"webExtensionId": "engine-reordered@search.mozilla.org",
"webExtensionVersion": "1.0",
"orderHint": 5000,
"appliesTo": [{
"included": { "everywhere": true },
"default": "yes"
"excluded": { "locales": { "matches": ["de", "fr"] } },
"default": "no"
}]
}
]

Просмотреть файл

@ -0,0 +1,24 @@
{
"data": [
{
"engineName": "engine1",
"webExtensionId": "engine1@search.mozilla.org",
"webExtensionVersion": "1.0",
"orderHint": 10000,
"appliesTo": [{
"included": { "everywhere": true },
"default": "yes"
}]
},
{
"engineName": "engine2",
"webExtensionId": "engine2@search.mozilla.org",
"webExtensionVersion": "1.0",
"orderHint": 7000,
"appliesTo": [{
"included": { "everywhere": true },
"default": "no"
}]
}
]
}

Просмотреть файл

@ -12,6 +12,7 @@ add_task(function test_setup() {
SearchUtils.BROWSER_SEARCH_PREF + "separatePrivateDefault",
true
);
Services.prefs.setCharPref("browser.search.region", "US");
});
add_task(async function test_listJSONlocale() {

Просмотреть файл

@ -29,17 +29,39 @@ add_task(async function test_searchOrderJSON_no_separate_private() {
false
);
await checkOrder([
// Default engine
"Test search engine",
// Two engines listed in searchOrder.
"engine-resourceicon",
"engine-chromeicon",
// Rest of the engines in order.
"engine-pref",
"engine-rel-searchform-purpose",
"Test search engine (Reordered)",
]);
// With modern configuration, we have a slightly different order, since the
// default private engine will get placed second, regardless of if the
// separate private engine is enabled or not.
if (
Services.prefs.getBoolPref(
SearchUtils.BROWSER_SEARCH_PREF + "modernConfig",
false
)
) {
await checkOrder([
// Default engines
"Test search engine",
"engine-pref",
// Two engines listed in searchOrder.
"engine-resourceicon",
"engine-chromeicon",
// Rest of the engines in order.
"engine-rel-searchform-purpose",
"Test search engine (Reordered)",
]);
} else {
await checkOrder([
// Default engine
"Test search engine",
// Two engines listed in searchOrder.
"engine-resourceicon",
"engine-chromeicon",
// Rest of the engines in order.
"engine-pref",
"engine-rel-searchform-purpose",
"Test search engine (Reordered)",
]);
}
});
add_task(async function test_searchOrderJSON_separate_private() {

Просмотреть файл

@ -26,6 +26,16 @@ skip-if = true # Is confusing
[test_invalid_engine_from_dir.js]
[test_json_cache_ignorelist.js]
support-files = data/search_ignorelist.json
[test_list_json_locale.js]
[test_list_json_no_private_default.js]
support-files =
data1/engine1/manifest.json
data1/engine2/manifest.json
data1/list.json
data1/engines.json
[test_list_json_searchdefault_distro.js]
[test_list_json_searchdefault.js]
[test_list_json_searchorder.js]
[test_location_error.js]
[test_location_malformed_json.js]
[test_location_timeout_xhr.js]

Просмотреть файл

@ -74,15 +74,6 @@ support-files =
[test_require_engines_in_cache.js]
# Testing with list.json specifically - Bug 1582942
[test_list_json_locale.js]
[test_list_json_no_private_default.js]
support-files =
data1/engine1/manifest.json
data1/engine2/manifest.json
data1/list.json
[test_list_json_searchdefault.js]
[test_list_json_searchdefault_distro.js]
[test_list_json_searchorder.js]
# Use geoSpecificDefaults - Bug 1542269
[test_maybereloadengine_update.js]

Просмотреть файл

@ -1,4 +1,3 @@
!= chrome://reftest/content/toolkit/reftests/textbox-multiline-default-value.xul chrome://reftest/content/toolkit/reftests/textbox-multiline-empty.xul
== videocontrols-dynamically-add-cc.html videocontrols-dynamically-add-cc-ref.html
== audio-with-bogus-url.html audio-with-bogus-url-ref.html
== audio-dynamically-change-small-width.html audio-dynamically-change-small-width-ref.html

Просмотреть файл

@ -1,5 +0,0 @@
<?xml version='1.0'?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="test textbox multiline">
<textbox multiline='true' value='foobar'></textbox>
</window>

Просмотреть файл

@ -1,5 +0,0 @@
<?xml version='1.0'?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="test textbox multiline">
<textbox multiline='true'></textbox>
</window>

Просмотреть файл

@ -109,7 +109,7 @@
<hbox class="ac-separator" align="center">
<description class="ac-separator-text" value="—"/>
</hbox>
<hbox class="ac-url" align="center">
<hbox class="ac-url" align="center" aria-hidden="true">
<description class="ac-text-overflow-container">
<description class="ac-url-text"/>
</description>
@ -150,23 +150,6 @@
return this.querySelector(".ac-action-text");
}
get label() {
// This property is a string that is read aloud by screen readers,
// so it must not contain anything that should not be user-facing.
let parts = [this.getAttribute("title"), this.getAttribute("displayurl")];
let label = parts.filter(str => str).join(" ");
// allow consumers that have extended popups to override
// the label values for the richlistitems
let panel = this.parentNode.parentNode;
if (panel.createResultLabel) {
return panel.createResultLabel(this, label);
}
return label;
}
get _stringBundle() {
if (!this.__stringBundle) {
this.__stringBundle = Services.strings.createBundle(

Просмотреть файл

@ -1593,19 +1593,22 @@
purgeSessionHistory() {
if (this.isRemoteBrowser) {
try {
this.messageManager.sendAsyncMessage("Browser:PurgeSessionHistory");
} catch (ex) {
// This can throw if the browser has started to go away.
if (ex.result != Cr.NS_ERROR_NOT_INITIALIZED) {
throw ex;
}
}
this._remoteWebNavigationImpl.canGoBack = false;
this._remoteWebNavigationImpl.canGoForward = false;
return;
}
this.messageManager.sendAsyncMessage("Browser:PurgeSessionHistory");
try {
this.sendMessageToActor(
"Browser:PurgeSessionHistory",
{},
"PurgeSessionHistory",
true
);
} catch (ex) {
// This can throw if the browser has started to go away.
if (ex.result != Cr.NS_ERROR_NOT_INITIALIZED) {
throw ex;
}
}
}
createAboutBlankContentViewer(aPrincipal, aStoragePrincipal) {

Просмотреть файл

@ -275,6 +275,12 @@ let ACTORS = {
allFrames: true,
},
PurgeSessionHistory: {
child: {
moduleURI: "resource://gre/actors/PurgeSessionHistoryChild.jsm",
},
allFrames: true,
},
};
let LEGACY_ACTORS = {
@ -370,13 +376,6 @@ let LEGACY_ACTORS = {
},
},
PurgeSessionHistory: {
child: {
module: "resource://gre/actors/PurgeSessionHistoryChild.jsm",
messages: ["Browser:PurgeSessionHistory"],
},
},
SelectionSource: {
child: {
module: "resource://gre/actors/SelectionSourceChild.jsm",

Просмотреть файл

@ -57,20 +57,6 @@ search-textbox[disabled="true"] {
color: GrayText;
}
/* ::::: plain textbox ::::: */
textbox.plain {
-moz-appearance: none !important;
background-color: transparent;
padding: 0px !important;
margin: 0px !important;
border: none !important;
}
textbox.plain html|*.textbox-input {
padding: 0px !important;
}
/* ::::: search textbox ::::: */
search-textbox:not([searchbutton]) > .textbox-search-sign {

Просмотреть файл

@ -49,18 +49,6 @@ search-textbox[disabled="true"] {
color: GrayText;
}
textbox.plain {
-moz-appearance: none !important;
background-color: transparent;
padding: 0px !important;
margin: 0px !important;
border: none !important;
}
textbox.plain html|*.textbox-input {
padding: 0px !important;
}
/* ::::: search box ::::: */
search-textbox {

Просмотреть файл

@ -63,20 +63,6 @@ search-textbox[disabled="true"] {
color: GrayText;
}
/* ::::: plain textbox ::::: */
textbox.plain {
-moz-appearance: none !important;
background-color: transparent;
padding: 0px !important;
margin: 0px !important;
border: none !important;
}
textbox.plain html|*.textbox-input {
padding: 0px !important;
}
/* ::::: search textbox ::::: */
search-textbox:not([searchbutton]) > .textbox-search-sign {

Просмотреть файл

@ -37,7 +37,17 @@ def lint(files, config, **kwargs):
cmd = ['python2', os.path.join(tests_dir, 'wpt'), 'lint', '--json'] + files
log.debug("Command: {}".format(' '.join(cmd)))
proc = ProcessHandler(cmd, env=os.environ, processOutputLine=process_line)
proc = ProcessHandler(cmd, env=os.environ, processOutputLine=process_line,
universal_newlines=True)
if sys.platform == 'win32':
# Workaround for bug 1585702. According to the win32 docs,
# CreateProcess will use the calling process's env by default. Since we
# are passing in `os.environ` wholesale anyway, setting the env to
# `None` shouldn't make a difference. An alternative workaround would
# be to stop using mozprocess here and use subprocess directly.
proc.env = None
proc.run()
try:
proc.wait()