зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
38eb5bb32a
|
@ -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&>kWidget) load 1157994.html
|
|||
load 1158427.html
|
||||
skip-if(verify&&isDebugBuild&>kWidget) 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()
|
||||
|
|
Загрузка…
Ссылка в новой задаче