Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Andreea Pavel 2018-04-26 17:03:43 +03:00
Родитель dd9e28b9cc bcb74332bf
Коммит 17a7053b0d
44 изменённых файлов: 1482 добавлений и 845 удалений

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

@ -0,0 +1,377 @@
// The following parameters are parsed from the error URL:
// e - the error code
// s - custom CSS class to allow alternate styling/favicons
// d - error description
// captive - "true" to indicate we're behind a captive portal.
// Any other value is ignored.
// Note that this file uses document.documentURI to get
// the URL (with the format from above). This is because
// document.location.href gets the current URI off the docshell,
// which is the URL displayed in the location bar, i.e.
// the URI that the user attempted to load.
let searchParams = new URLSearchParams(document.documentURI.split("?")[1]);
// Set to true on init if the error code is nssBadCert.
let gIsCertError;
function getErrorCode() {
return searchParams.get("e");
}
function getCSSClass() {
return searchParams.get("s");
}
function getDescription() {
return searchParams.get("d");
}
function isCaptive() {
return searchParams.get("captive") == "true";
}
function retryThis(buttonEl) {
// Note: The application may wish to handle switching off "offline mode"
// before this event handler runs, but using a capturing event handler.
// Session history has the URL of the page that failed
// to load, not the one of the error page. So, just call
// reload(), which will also repost POST data correctly.
try {
location.reload();
} catch (e) {
// We probably tried to reload a URI that caused an exception to
// occur; e.g. a nonexistent file.
}
buttonEl.disabled = true;
}
function toggleDisplay(node) {
const toggle = {
"": "block",
"none": "block",
"block": "none"
};
return (node.style.display = toggle[node.style.display]);
}
function showCertificateErrorReporting() {
// Display error reporting UI
document.getElementById("certificateErrorReporting").style.display = "block";
}
function showPrefChangeContainer() {
const panel = document.getElementById("prefChangeContainer");
panel.style.display = "block";
document.getElementById("netErrorButtonContainer").style.display = "none";
document.getElementById("prefResetButton").addEventListener("click", function resetPreferences(e) {
const event = new CustomEvent("AboutNetErrorResetPreferences", {bubbles: true});
document.dispatchEvent(event);
});
addAutofocus("prefResetButton", "beforeend");
}
function setupAdvancedButton() {
// Get the hostname and add it to the panel
var panel = document.getElementById("badCertAdvancedPanel");
for (var span of panel.querySelectorAll("span.hostname")) {
span.textContent = document.location.hostname;
}
// Register click handler for the weakCryptoAdvancedPanel
document.getElementById("advancedButton")
.addEventListener("click", function togglePanelVisibility() {
toggleDisplay(panel);
if (gIsCertError) {
// Toggling the advanced panel must ensure that the debugging
// information panel is hidden as well, since it's opened by the
// error code link in the advanced panel.
var div = document.getElementById("certificateErrorDebugInformation");
div.style.display = "none";
}
if (panel.style.display == "block") {
// send event to trigger telemetry ping
var event = new CustomEvent("AboutNetErrorUIExpanded", {bubbles: true});
document.dispatchEvent(event);
}
});
if (!gIsCertError) {
return;
}
if (getCSSClass() == "expertBadCert") {
toggleDisplay(document.getElementById("badCertAdvancedPanel"));
// Toggling the advanced panel must ensure that the debugging
// information panel is hidden as well, since it's opened by the
// error code link in the advanced panel.
var div = document.getElementById("certificateErrorDebugInformation");
div.style.display = "none";
}
disallowCertOverridesIfNeeded();
}
function disallowCertOverridesIfNeeded() {
var cssClass = getCSSClass();
// Disallow overrides if this is a Strict-Transport-Security
// host and the cert is bad (STS Spec section 7.3) or if the
// certerror is in a frame (bug 633691).
if (cssClass == "badStsCert" || window != top) {
document.getElementById("exceptionDialogButton").setAttribute("hidden", "true");
}
if (cssClass == "badStsCert") {
document.getElementById("badStsCertExplanation").removeAttribute("hidden");
}
}
function initPage() {
var err = getErrorCode();
// List of error pages with an illustration.
let illustratedErrors = [
"malformedURI", "dnsNotFound", "connectionFailure", "netInterrupt",
"netTimeout", "netReset", "netOffline",
];
if (illustratedErrors.includes(err)) {
document.body.classList.add("illustrated", err);
}
if (err == "blockedByPolicy") {
document.body.classList.add("blocked");
}
gIsCertError = (err == "nssBadCert");
// Only worry about captive portals if this is a cert error.
let showCaptivePortalUI = isCaptive() && gIsCertError;
if (showCaptivePortalUI) {
err = "captivePortal";
}
let pageTitle = document.getElementById("ept_" + err);
if (pageTitle) {
document.title = pageTitle.textContent;
}
// if it's an unknown error or there's no title or description
// defined, get the generic message
var errTitle = document.getElementById("et_" + err);
var errDesc = document.getElementById("ed_" + err);
if (!errTitle || !errDesc) {
errTitle = document.getElementById("et_generic");
errDesc = document.getElementById("ed_generic");
}
// eslint-disable-next-line no-unsanitized/property
document.querySelector(".title-text").innerHTML = errTitle.innerHTML;
var sd = document.getElementById("errorShortDescText");
if (sd) {
if (gIsCertError) {
// eslint-disable-next-line no-unsanitized/property
sd.innerHTML = errDesc.innerHTML;
} else {
sd.textContent = getDescription();
}
}
if (showCaptivePortalUI) {
initPageCaptivePortal();
return;
}
if (gIsCertError) {
initPageCertError();
return;
}
addAutofocus("errorTryAgain");
document.body.classList.add("neterror");
var ld = document.getElementById("errorLongDesc");
if (ld) {
// eslint-disable-next-line no-unsanitized/property
ld.innerHTML = errDesc.innerHTML;
}
if (err == "sslv3Used") {
document.getElementById("learnMoreContainer").style.display = "block";
let learnMoreLink = document.getElementById("learnMoreLink");
learnMoreLink.href = "https://support.mozilla.org/kb/how-resolve-sslv3-error-messages-firefox";
document.body.className = "certerror";
}
// remove undisplayed errors to avoid bug 39098
var errContainer = document.getElementById("errorContainer");
errContainer.remove();
var className = getCSSClass();
if (className && className != "expertBadCert") {
// Associate a CSS class with the root of the page, if one was passed in,
// to allow custom styling.
// Not "expertBadCert" though, don't want to deal with the favicon
document.documentElement.className = className;
// Also, if they specified a CSS class, they must supply their own
// favicon. In order to trigger the browser to repaint though, we
// need to remove/add the link element.
var favicon = document.getElementById("favicon");
var faviconParent = favicon.parentNode;
faviconParent.removeChild(favicon);
favicon.setAttribute("href", "chrome://global/skin/icons/" + className + "_favicon.png");
faviconParent.appendChild(favicon);
}
if (err == "remoteXUL") {
// Remove the "Try again" button for remote XUL errors given that
// it is useless.
document.getElementById("netErrorButtonContainer").style.display = "none";
}
if (err == "cspBlocked") {
// Remove the "Try again" button for CSP violations, since it's
// almost certainly useless. (Bug 553180)
document.getElementById("netErrorButtonContainer").style.display = "none";
}
window.addEventListener("AboutNetErrorOptions", function(evt) {
// Pinning errors are of type nssFailure2
if (getErrorCode() == "nssFailure2") {
let shortDesc = document.getElementById("errorShortDescText").textContent;
document.getElementById("learnMoreContainer").style.display = "block";
let learnMoreLink = document.getElementById("learnMoreLink");
// nssFailure2 also gets us other non-overrideable errors. Choose
// a "learn more" link based on description:
if (shortDesc.includes("MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE")) {
learnMoreLink.href = "https://support.mozilla.org/kb/certificate-pinning-reports";
}
var options = JSON.parse(evt.detail);
if (options && options.enabled) {
var checkbox = document.getElementById("automaticallyReportInFuture");
showCertificateErrorReporting();
if (options.automatic) {
// set the checkbox
checkbox.checked = true;
}
checkbox.addEventListener("change", function(changeEvt) {
var event = new CustomEvent("AboutNetErrorSetAutomatic",
{bubbles: true,
detail: changeEvt.target.checked});
document.dispatchEvent(event);
});
}
const hasPrefStyleError = [
"interrupted", // This happens with subresources that are above the max tls
"SSL_ERROR_PROTOCOL_VERSION_ALERT",
"SSL_ERROR_UNSUPPORTED_VERSION",
"SSL_ERROR_NO_CYPHER_OVERLAP",
"SSL_ERROR_NO_CIPHERS_SUPPORTED"
].some((substring) => shortDesc.includes(substring));
// If it looks like an error that is user config based
if (getErrorCode() == "nssFailure2" && hasPrefStyleError && options && options.changedCertPrefs) {
showPrefChangeContainer();
}
}
if (getErrorCode() == "sslv3Used") {
document.getElementById("advancedButton").style.display = "none";
}
}, true, true);
var event = new CustomEvent("AboutNetErrorLoad", {bubbles: true});
document.dispatchEvent(event);
if (err == "inadequateSecurityError" || err == "blockedByPolicy") {
// Remove the "Try again" button from pages that don't need it.
// For HTTP/2 inadequate security or pages blocked by policy, trying
// again won't help.
document.getElementById("errorTryAgain").style.display = "none";
var container = document.getElementById("errorLongDesc");
for (var span of container.querySelectorAll("span.hostname")) {
span.textContent = document.location.hostname;
}
}
}
function initPageCaptivePortal() {
document.body.className = "captiveportal";
document.getElementById("openPortalLoginPageButton")
.addEventListener("click", () => {
let event = new CustomEvent("AboutNetErrorOpenCaptivePortal", {bubbles: true});
document.dispatchEvent(event);
});
addAutofocus("openPortalLoginPageButton");
setupAdvancedButton();
// When the portal is freed, an event is generated by the frame script
// that we can pick up and attempt to reload the original page.
window.addEventListener("AboutNetErrorCaptivePortalFreed", () => {
document.location.reload();
});
}
function initPageCertError() {
document.body.className = "certerror";
for (let host of document.querySelectorAll(".hostname")) {
host.textContent = document.location.hostname;
}
addAutofocus("returnButton");
setupAdvancedButton();
document.getElementById("learnMoreContainer").style.display = "block";
let checkbox = document.getElementById("automaticallyReportInFuture");
checkbox.addEventListener("change", function({target: {checked}}) {
document.dispatchEvent(new CustomEvent("AboutNetErrorSetAutomatic", {
detail: checked,
bubbles: true
}));
});
addEventListener("AboutNetErrorOptions", function(event) {
var options = JSON.parse(event.detail);
if (options && options.enabled) {
// Display error reporting UI
document.getElementById("certificateErrorReporting").style.display = "block";
// set the checkbox
checkbox.checked = !!options.automatic;
}
if (options && options.hideAddExceptionButton) {
document.querySelector(".exceptionDialogButtonContainer").hidden = true;
}
}, true, true);
let event = new CustomEvent("AboutNetErrorLoad", {bubbles: true});
document.getElementById("advancedButton").dispatchEvent(event);
}
/* Only do autofocus if we're the toplevel frame; otherwise we
don't want to call attention to ourselves! The key part is
that autofocus happens on insertion into the tree, so we
can remove the button, add @autofocus, and reinsert the
button.
*/
function addAutofocus(buttonId, position = "afterbegin") {
if (window.top == window) {
var button = document.getElementById(buttonId);
var parent = button.parentNode;
button.remove();
button.setAttribute("autofocus", "true");
parent.insertAdjacentElement(position, button);
}
}
let errorTryAgain = document.getElementById("errorTryAgain");
errorTryAgain.addEventListener("click", function() {
retryThis(this);
});
// Note: It is important to run the script this way, instead of using
// an onload handler. This is because error pages are loaded as
// LOAD_BACKGROUND, which means that onload handlers will not be executed.
initPage();

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

@ -19,382 +19,12 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Security-Policy" content="default-src chrome:" />
<title>&loadError.label;</title>
<link rel="stylesheet" href="chrome://browser/skin/aboutNetError.css" type="text/css" media="all" />
<!-- If the location of the favicon is changed here, the FAVICON_ERRORPAGE_URL symbol in
toolkit/components/places/src/nsFaviconService.h should be updated. -->
<link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/warning-16.png"/>
<script type="application/javascript"><![CDATA[
// The following parameters are parsed from the error URL:
// e - the error code
// s - custom CSS class to allow alternate styling/favicons
// d - error description
// captive - "true" to indicate we're behind a captive portal.
// Any other value is ignored.
// Note that this file uses document.documentURI to get
// the URL (with the format from above). This is because
// document.location.href gets the current URI off the docshell,
// which is the URL displayed in the location bar, i.e.
// the URI that the user attempted to load.
let searchParams = new URLSearchParams(document.documentURI.split("?")[1]);
// Set to true on init if the error code is nssBadCert.
let gIsCertError;
function getErrorCode() {
return searchParams.get("e");
}
function getCSSClass() {
return searchParams.get("s");
}
function getDescription() {
return searchParams.get("d");
}
function isCaptive() {
return searchParams.get("captive") == "true";
}
function retryThis(buttonEl) {
// Note: The application may wish to handle switching off "offline mode"
// before this event handler runs, but using a capturing event handler.
// Session history has the URL of the page that failed
// to load, not the one of the error page. So, just call
// reload(), which will also repost POST data correctly.
try {
location.reload();
} catch (e) {
// We probably tried to reload a URI that caused an exception to
// occur; e.g. a nonexistent file.
}
buttonEl.disabled = true;
}
function toggleDisplay(node) {
const toggle = {
"": "block",
"none": "block",
"block": "none"
};
return (node.style.display = toggle[node.style.display]);
}
function showCertificateErrorReporting() {
// Display error reporting UI
document.getElementById("certificateErrorReporting").style.display = "block";
}
function showPrefChangeContainer() {
const panel = document.getElementById("prefChangeContainer");
panel.style.display = "block";
document.getElementById("netErrorButtonContainer").style.display = "none";
document.getElementById("prefResetButton").addEventListener("click", function resetPreferences(e) {
const event = new CustomEvent("AboutNetErrorResetPreferences", {bubbles: true});
document.dispatchEvent(event);
});
addAutofocus("prefResetButton", "beforeend");
}
function setupAdvancedButton() {
// Get the hostname and add it to the panel
var panel = document.getElementById("badCertAdvancedPanel");
for (var span of panel.querySelectorAll("span.hostname")) {
span.textContent = document.location.hostname;
}
// Register click handler for the weakCryptoAdvancedPanel
document.getElementById("advancedButton")
.addEventListener("click", function togglePanelVisibility() {
toggleDisplay(panel);
if (gIsCertError) {
// Toggling the advanced panel must ensure that the debugging
// information panel is hidden as well, since it's opened by the
// error code link in the advanced panel.
var div = document.getElementById("certificateErrorDebugInformation");
div.style.display = "none";
}
if (panel.style.display == "block") {
// send event to trigger telemetry ping
var event = new CustomEvent("AboutNetErrorUIExpanded", {bubbles: true});
document.dispatchEvent(event);
}
});
if (!gIsCertError) {
return;
}
if (getCSSClass() == "expertBadCert") {
toggleDisplay(document.getElementById("badCertAdvancedPanel"));
// Toggling the advanced panel must ensure that the debugging
// information panel is hidden as well, since it's opened by the
// error code link in the advanced panel.
var div = document.getElementById("certificateErrorDebugInformation");
div.style.display = "none";
}
disallowCertOverridesIfNeeded();
}
function disallowCertOverridesIfNeeded() {
var cssClass = getCSSClass();
// Disallow overrides if this is a Strict-Transport-Security
// host and the cert is bad (STS Spec section 7.3) or if the
// certerror is in a frame (bug 633691).
if (cssClass == "badStsCert" || window != top) {
document.getElementById("exceptionDialogButton").setAttribute("hidden", "true");
}
if (cssClass == "badStsCert") {
document.getElementById("badStsCertExplanation").removeAttribute("hidden");
}
}
function initPage() {
var err = getErrorCode();
// List of error pages with an illustration.
let illustratedErrors = [
"malformedURI", "dnsNotFound", "connectionFailure", "netInterrupt",
"netTimeout", "netReset", "netOffline",
];
if (illustratedErrors.includes(err)) {
document.body.classList.add("illustrated", err);
}
if (err == "blockedByPolicy") {
document.body.classList.add("blocked");
}
gIsCertError = (err == "nssBadCert");
// Only worry about captive portals if this is a cert error.
let showCaptivePortalUI = isCaptive() && gIsCertError;
if (showCaptivePortalUI) {
err = "captivePortal";
}
let pageTitle = document.getElementById("ept_" + err);
if (pageTitle) {
document.title = pageTitle.textContent;
}
// if it's an unknown error or there's no title or description
// defined, get the generic message
var errTitle = document.getElementById("et_" + err);
var errDesc = document.getElementById("ed_" + err);
if (!errTitle || !errDesc) {
errTitle = document.getElementById("et_generic");
errDesc = document.getElementById("ed_generic");
}
// eslint-disable-next-line no-unsanitized/property
document.querySelector(".title-text").innerHTML = errTitle.innerHTML;
var sd = document.getElementById("errorShortDescText");
if (sd) {
if (gIsCertError) {
// eslint-disable-next-line no-unsanitized/property
sd.innerHTML = errDesc.innerHTML;
} else {
sd.textContent = getDescription();
}
}
if (showCaptivePortalUI) {
initPageCaptivePortal();
return;
}
if (gIsCertError) {
initPageCertError();
return;
}
addAutofocus("errorTryAgain");
document.body.classList.add("neterror");
var ld = document.getElementById("errorLongDesc");
if (ld) {
// eslint-disable-next-line no-unsanitized/property
ld.innerHTML = errDesc.innerHTML;
}
if (err == "sslv3Used") {
document.getElementById("learnMoreContainer").style.display = "block";
let learnMoreLink = document.getElementById("learnMoreLink");
learnMoreLink.href = "https://support.mozilla.org/kb/how-resolve-sslv3-error-messages-firefox";
document.body.className = "certerror";
}
// remove undisplayed errors to avoid bug 39098
var errContainer = document.getElementById("errorContainer");
errContainer.remove();
var className = getCSSClass();
if (className && className != "expertBadCert") {
// Associate a CSS class with the root of the page, if one was passed in,
// to allow custom styling.
// Not "expertBadCert" though, don't want to deal with the favicon
document.documentElement.className = className;
// Also, if they specified a CSS class, they must supply their own
// favicon. In order to trigger the browser to repaint though, we
// need to remove/add the link element.
var favicon = document.getElementById("favicon");
var faviconParent = favicon.parentNode;
faviconParent.removeChild(favicon);
favicon.setAttribute("href", "chrome://global/skin/icons/" + className + "_favicon.png");
faviconParent.appendChild(favicon);
}
if (err == "remoteXUL") {
// Remove the "Try again" button for remote XUL errors given that
// it is useless.
document.getElementById("netErrorButtonContainer").style.display = "none";
}
if (err == "cspBlocked") {
// Remove the "Try again" button for CSP violations, since it's
// almost certainly useless. (Bug 553180)
document.getElementById("netErrorButtonContainer").style.display = "none";
}
window.addEventListener("AboutNetErrorOptions", function(evt) {
// Pinning errors are of type nssFailure2
if (getErrorCode() == "nssFailure2") {
let shortDesc = document.getElementById("errorShortDescText").textContent;
document.getElementById("learnMoreContainer").style.display = "block";
let learnMoreLink = document.getElementById("learnMoreLink");
// nssFailure2 also gets us other non-overrideable errors. Choose
// a "learn more" link based on description:
if (shortDesc.includes("MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE")) {
learnMoreLink.href = "https://support.mozilla.org/kb/certificate-pinning-reports";
}
var options = JSON.parse(evt.detail);
if (options && options.enabled) {
var checkbox = document.getElementById("automaticallyReportInFuture");
showCertificateErrorReporting();
if (options.automatic) {
// set the checkbox
checkbox.checked = true;
}
checkbox.addEventListener("change", function(changeEvt) {
var event = new CustomEvent("AboutNetErrorSetAutomatic",
{bubbles: true,
detail: changeEvt.target.checked});
document.dispatchEvent(event);
});
}
const hasPrefStyleError = [
"interrupted", // This happens with subresources that are above the max tls
"SSL_ERROR_PROTOCOL_VERSION_ALERT",
"SSL_ERROR_UNSUPPORTED_VERSION",
"SSL_ERROR_NO_CYPHER_OVERLAP",
"SSL_ERROR_NO_CIPHERS_SUPPORTED"
].some((substring) => shortDesc.includes(substring));
// If it looks like an error that is user config based
if (getErrorCode() == "nssFailure2" && hasPrefStyleError && options && options.changedCertPrefs) {
showPrefChangeContainer();
}
}
if (getErrorCode() == "sslv3Used") {
document.getElementById("advancedButton").style.display = "none";
}
}, true, true);
var event = new CustomEvent("AboutNetErrorLoad", {bubbles: true});
document.dispatchEvent(event);
if (err == "inadequateSecurityError" || err == "blockedByPolicy") {
// Remove the "Try again" button from pages that don't need it.
// For HTTP/2 inadequate security or pages blocked by policy, trying
// again won't help.
document.getElementById("errorTryAgain").style.display = "none";
var container = document.getElementById("errorLongDesc");
for (var span of container.querySelectorAll("span.hostname")) {
span.textContent = document.location.hostname;
}
}
}
function initPageCaptivePortal() {
document.body.className = "captiveportal";
document.getElementById("openPortalLoginPageButton")
.addEventListener("click", () => {
let event = new CustomEvent("AboutNetErrorOpenCaptivePortal", {bubbles: true});
document.dispatchEvent(event);
});
addAutofocus("openPortalLoginPageButton");
setupAdvancedButton();
// When the portal is freed, an event is generated by the frame script
// that we can pick up and attempt to reload the original page.
window.addEventListener("AboutNetErrorCaptivePortalFreed", () => {
document.location.reload();
});
}
function initPageCertError() {
document.body.className = "certerror";
for (let host of document.querySelectorAll(".hostname")) {
host.textContent = document.location.hostname;
}
addAutofocus("returnButton");
setupAdvancedButton();
document.getElementById("learnMoreContainer").style.display = "block";
let checkbox = document.getElementById("automaticallyReportInFuture");
checkbox.addEventListener("change", function({target: {checked}}) {
document.dispatchEvent(new CustomEvent("AboutNetErrorSetAutomatic", {
detail: checked,
bubbles: true
}));
});
addEventListener("AboutNetErrorOptions", function(event) {
var options = JSON.parse(event.detail);
if (options && options.enabled) {
// Display error reporting UI
document.getElementById("certificateErrorReporting").style.display = "block";
// set the checkbox
checkbox.checked = !!options.automatic;
}
if (options && options.hideAddExceptionButton) {
document.querySelector(".exceptionDialogButtonContainer").hidden = true;
}
}, true, true);
let event = new CustomEvent("AboutNetErrorLoad", {bubbles: true});
document.getElementById("advancedButton").dispatchEvent(event);
}
/* Only do autofocus if we're the toplevel frame; otherwise we
don't want to call attention to ourselves! The key part is
that autofocus happens on insertion into the tree, so we
can remove the button, add @autofocus, and reinsert the
button.
*/
function addAutofocus(buttonId, position = "afterbegin") {
if (window.top == window) {
var button = document.getElementById(buttonId);
var parent = button.parentNode;
button.remove();
button.setAttribute("autofocus", "true");
parent.insertAdjacentElement(position, button);
}
}
]]></script>
</head>
<body dir="&locale.dir;">
@ -486,11 +116,11 @@
</div>
<p id="badStsCertExplanation" hidden="true">&certerror.whatShouldIDo.badStsCertExplanation;</p>
<div id="wrongSystemTimePanel" style="display: none;">
<div id="wrongSystemTimePanel">
&certerror.wrongSystemTime2;
</div>
<div id="wrongSystemTimeWithoutReferencePanel" style="display: none;">
<div id="wrongSystemTimeWithoutReferencePanel">
&certerror.wrongSystemTimeWithoutReference;
</div>
@ -524,7 +154,7 @@
</div>
<div id="netErrorButtonContainer" class="button-container">
<button id="errorTryAgain" class="primary" autocomplete="off" onclick="retryThis(this);">&retry.label;</button>
<button id="errorTryAgain" class="primary" autocomplete="off">&retry.label;</button>
</div>
<div id="advancedPanelContainer">
@ -542,15 +172,6 @@
</div>
</div>
</div>
<!--
- Note: It is important to run the script this way, instead of using
- an onload handler. This is because error pages are loaded as
- LOAD_BACKGROUND, which means that onload handlers will not be executed.
-->
<script type="application/javascript">
initPage();
</script>
</body>
<script type="application/javascript" src="chrome://browser/content/aboutNetError.js"/>
</html>

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

@ -40,6 +40,7 @@ browser.jar:
content/browser/illustrations/error-malformed-url.svg (content/illustrations/error-malformed-url.svg)
content/browser/illustrations/under-construction.svg (content/illustrations/under-construction.svg)
content/browser/aboutNetError.xhtml (content/aboutNetError.xhtml)
content/browser/aboutNetError.js (content/aboutNetError.js)
content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png)
content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png)
content/browser/aboutTabCrashed.css (content/aboutTabCrashed.css)

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

@ -211,3 +211,11 @@ span#hostname {
.malformedURI #errorTryAgain {
display: none;
}
#wrongSystemTimePanel {
display: none;
}
#wrongSystemTimeWithoutReferencePanel {
display: none;
}

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

@ -0,0 +1,13 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import buildconfig
import subprocess
import sys
def main(output, lib_file, *scripts):
for script in scripts:
retcode = subprocess.call([sys.executable, script], cwd=buildconfig.topsrcdir)
if retcode != 0:
raise Exception(script + " failed")

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

@ -787,7 +787,7 @@ CreateInterfaceObject(JSContext* cx, JS::Handle<JSObject*> global,
}
if (isChrome && !JS_DefineFunction(cx, constructor, "isInstance",
InterfaceHasInstance, 1,
InterfaceIsInstance, 1,
// Don't bother making it enumerable
0)) {
return nullptr;

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

@ -623,9 +623,7 @@ def InterfacePrototypeObjectProtoGetter(descriptor):
protoGetter = "GetNamedPropertiesObject"
protoHandleGetter = None
elif parentProtoName is None:
if descriptor.interface.getExtendedAttribute("ArrayClass"):
protoGetter = "JS::GetRealmArrayPrototype"
elif descriptor.interface.getExtendedAttribute("ExceptionClass"):
if descriptor.interface.getExtendedAttribute("ExceptionClass"):
protoGetter = "JS::GetRealmErrorPrototype"
elif descriptor.interface.isIteratorInterface():
protoGetter = "JS::GetRealmIteratorPrototype"

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

@ -1683,14 +1683,6 @@ class IDLInterface(IDLInterfaceOrNamespace):
elif newMethod not in self.namedConstructors:
raise WebIDLError("NamedConstructor conflicts with a NamedConstructor of a different interface",
[method.location, newMethod.location])
elif (identifier == "ArrayClass"):
if not attr.noArguments():
raise WebIDLError("[ArrayClass] must take no arguments",
[attr.location])
if self.parent:
raise WebIDLError("[ArrayClass] must not be specified on "
"an interface with inherited interfaces",
[attr.location, self.location])
elif (identifier == "ExceptionClass"):
if not attr.noArguments():
raise WebIDLError("[ExceptionClass] must take no arguments",

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

@ -374,32 +374,3 @@ def WebIDLTest(parser, harness):
threw = True
harness.ok(threw,
"Should not allow unknown extended attributes on interfaces")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface B {};
[ArrayClass]
interface A : B {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should not allow [ArrayClass] on interfaces with parents")
parser = parser.reset()
threw = False
try:
parser.parse("""
[ArrayClass]
interface A {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(not threw,
"Should allow [ArrayClass] on interfaces without parents")

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

@ -13,3 +13,4 @@ support-files =
[test_bug1123516_maplikesetlikechrome.xul]
skip-if = debug == false
[test_bug1287912.html]
[test_bug1457051.html]

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

@ -0,0 +1,34 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1457051
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1457051</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1457051 **/
ok(Element.isInstance(document.documentElement), "Basic isInstance works");
ok(!Element.isInstance(null),
"Passing null should return false without throwing");
ok(!Element.isInstance(5), "Passing 5 should return false without throwing");
var obj = Object.create(Element.prototype);
ok(obj instanceof Element, "instanceof should walk the proto chain");
ok(!Element.isInstance(obj), "isInstance should be a pure brand check");
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1457051">Mozilla Bug 1457051</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

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

@ -29,11 +29,8 @@ function doc(id) {
function checkElement(id, list, eps, doc) {
var e = (doc || document).getElementById(id);
var clientRects = e.getClientRects();
ok(clientRects instanceof e.ownerDocument.defaultView.Array,
"getClientRects retval should have Array.prototype on its proto chain");
clientRects.map(function(rect) {
ok(rect instanceof DOMRect, "Should have a DOMRect here");
});
ok(!(clientRects instanceof e.ownerDocument.defaultView.Array),
"getClientRects retval should not have Array.prototype on its proto chain");
is(clientRects.length, list.length, "getClientRects().length for element '" + id + "'");
var bounds = list.length > 0 ? list[0] : [0,0,0,0];
for (var i = 0; i < clientRects.length && i < list.length; ++i) {

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

@ -4,7 +4,6 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[ArrayClass]
interface DOMRectList {
readonly attribute unsigned long length;
getter DOMRect? item(unsigned long index);

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

@ -101,14 +101,14 @@ NS_IMETHODIMP
WorkerEventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
uint32_t aFlags)
{
nsCOMPtr<nsIRunnable> runnable(aRunnable);
MutexAutoLock lock(mMutex);
if (!mWorkerPrivate) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIRunnable> runnable(aRunnable);
if (mBehavior == Behavior::Hybrid) {
RefPtr<WorkerRunnable> r =
mWorkerPrivate->MaybeWrapAsWorkerRunnable(runnable.forget());

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

@ -1,4 +1,4 @@
52579
52616
0/nm
0th/pt
1/n1
@ -1524,6 +1524,7 @@ Billie/M
Billings/M
Billy/M
Bimini/M
Bing/M
Bink/M
Binky/M
Binnie/M
@ -5775,6 +5776,7 @@ IDE
IE
IED
IEEE
IIRC
IKEA/M
IL
IMDb/M
@ -6965,6 +6967,7 @@ Laocoon/M
Laos/M
Laotian/SM
Laplace/M
Laplacian
Lapland/MR
Lapp/SM
Lara/M
@ -9658,6 +9661,7 @@ Petronella/M
Petronilla/M
Petty/M
Peugeot/M
Peyronie's
Peyton/M
Pfc
Pfizer/M
@ -14712,6 +14716,7 @@ anticyclone/SM
anticyclonic
antidemocratic
antidepressant/MS
antiderivative/S
antidote/MS
antifa
antifascist/MS
@ -15370,6 +15375,7 @@ asymmetric
asymmetrical/Y
asymmetry/SM
asymptomatic
asymptote/S
asymptotic
asymptotically
asynchronicity
@ -15794,6 +15800,7 @@ bacteriologist/SM
bacteriology/M
bacterium/M
bad/MYP
badass/S
badder
baddest
baddie/M
@ -19985,6 +19992,8 @@ collide/DRSZG
collie/RSMZ
collier/M
colliery/SM
collinear
collinearity
collision/SM
collocate/MGNDSX
collocation/M
@ -21842,6 +21851,7 @@ cw
cwt
cyan/M
cyanide/M
cyanobacteria
cyber
cyberbully/SM
cybercafe/S
@ -22163,6 +22173,7 @@ decidable/U
decide/BZGDRS
decided/Y
deciduous
decile/S
deciliter/MS
decimal/SM
decimalization
@ -22862,6 +22873,7 @@ differ/DG
difference/IM
differences
different/IY
differentiable
differential/SM
differentiate/DSGN
differentiated/U
@ -23036,7 +23048,7 @@ disappointing/Y
disarming/Y
disastrous/Y
disbandment/M
disbarment/M
disbarment/MS
disbelieving/Y
disbursal/M
disburse/DSGL
@ -25135,6 +25147,8 @@ eutectic
euthanasia/M
euthanize/DSG
euthenics/M
eutrophic
eutrophication
evacuate/XDSGN
evacuation/M
evacuee/MS
@ -25572,11 +25586,13 @@ extravagance/MS
extravagant/Y
extravaganza/MS
extravehicular
extrema
extreme/PMYTRS
extremeness/M
extremism/M
extremist/MS
extremity/SM
extremum/S
extricable/I
extricate/GNDS
extrication/M
@ -27998,6 +28014,7 @@ globular
globule/MS
globulin/M
glockenspiel/SM
glom/SDG
gloom/M
gloomily
gloominess/M
@ -31316,6 +31333,7 @@ intact
intaglio/MS
integer/MS
integral/SMY
integrand
integrate/AEVNGSD
integration/EAM
integrator
@ -31459,6 +31477,7 @@ interpretation/AMS
interpretative
interpreted/U
interpreter/MS
interquartile
interracial
interred/E
interregnum/SM
@ -31584,6 +31603,7 @@ inventory/DSMG
inverse/SMY
invert/SMDRZG
inverter/M
invertible
invest/ASDGL
investigate/GNVDSX
investigation/M
@ -31748,6 +31768,7 @@ isomerism/M
isometric/S
isometrically
isometrics/M
isometry
isomorphic
isosceles
isotherm/SM
@ -32790,6 +32811,7 @@ lb/S
lbw
lea/SM
leach/DSG
leachate/S
lead/MDNRSZG
leader/M
leaderless
@ -35390,6 +35412,7 @@ monomania/M
monomaniac/MS
monomaniacal
monomer/SM
monomial
mononucleosis/M
monophonic
monoplane/SM
@ -35755,6 +35778,7 @@ multitask/GS
multitasking/M
multitude/SM
multitudinous
multivariable
multivariate
multiverse/SM
multivitamin/MS
@ -36407,6 +36431,7 @@ nitrogen/M
nitrogenous
nitroglycerin/M
nitroglycerine/M
nitty-gritty
nitwit/MS
nix/GMDS
no/SM
@ -36620,6 +36645,7 @@ nonmilitant
nonmilitary
nonnarcotic/SM
nonnative/MS
nonnegative
nonnegotiable
nonnuclear
nonnumerical
@ -36664,6 +36690,7 @@ nonracial
nonradioactive
nonrandom
nonreactive
nonreal
nonreciprocal/SM
nonreciprocating
nonrecognition/M
@ -37140,6 +37167,8 @@ octagon/MS
octagonal
octal
octane/MS
octant/S
octantal
octave/MS
octavo/MS
octet/SM
@ -37372,6 +37401,7 @@ opiate/SM
opine/GNXDS
opinion/M
opinionated
opioid/S
opium/M
opossum/MS
opp
@ -37896,6 +37926,7 @@ overreach/GDS
overreact/SDG
overreaction/SM
overrefined
overrich/P
overridden
override/MGS
overripe/M
@ -38295,6 +38326,7 @@ paramedical/MS
parameter/MS
parameterize/D
parametric
parametrize/D
paramilitary/SM
paramount
paramountcy
@ -39256,6 +39288,7 @@ phrenologist/SM
phrenology/M
phyla
phylactery/SM
phyllo
phylogeny/M
phylum/M
phys
@ -39324,6 +39357,7 @@ pie/SM
piebald/MS
piece/DSMG
piecemeal
piecewise
piecework/MRZ
pieceworker/M
piecrust/SM
@ -41332,6 +41366,7 @@ quartermaster/MS
quarterstaff/M
quarterstaves
quartet/SM
quartile/S
quarto/MS
quartz/M
quasar/MS
@ -41832,6 +41867,7 @@ rebrand/DG
rebuild/SG
rebuke/DSMG
rebuking/Y
rebuttable
rebuttal/MS
rec'd
rec/M
@ -42333,6 +42369,7 @@ reprise/SMG
reproach/GMDSB
reproachful/Y
reprobate/MS
reproducibility
reproductive
reprogramming
reproving/Y

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

@ -50,9 +50,6 @@
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include "nsIDOMNode.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
#include "nsGenericHTMLElement.h"
#include "nsRange.h"
#include "nsIPlaintextEditor.h"
@ -60,7 +57,6 @@
#include "nsIPrefService.h"
#include "nsIRunnable.h"
#include "nsISelection.h"
#include "nsISelectionPrivate.h"
#include "nsISelectionController.h"
#include "nsIServiceManager.h"
#include "nsITextServicesFilter.h"
@ -366,7 +362,7 @@ mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil)
// find the word on the old caret position, this is the one that we MAY need
// to check
RefPtr<nsRange> oldWord;
nsresult rv = aWordUtil.GetRangeForWord(oldAnchorNode->AsDOMNode(),
nsresult rv = aWordUtil.GetRangeForWord(oldAnchorNode,
static_cast<int32_t>(oldAnchorOffset),
getter_AddRefs(oldWord));
NS_ENSURE_SUCCESS(rv, rv);
@ -427,14 +423,14 @@ mozInlineSpellStatus::FillNoCheckRangeFromAnchor(
}
uint32_t anchorOffset = mAnchorRange->StartOffset();
return aWordUtil.GetRangeForWord(anchorNode->AsDOMNode(),
return aWordUtil.GetRangeForWord(anchorNode,
static_cast<int32_t>(anchorOffset),
getter_AddRefs(mNoCheckRange));
}
// mozInlineSpellStatus::GetDocument
//
// Returns the nsIDOMDocument object for the document for the
// Returns the nsIDocument object for the document for the
// current spellchecker.
nsIDocument*
@ -936,7 +932,7 @@ mozInlineSpellChecker::GetMisspelledWord(nsIDOMNode *aNode, int32_t aOffset,
if (NS_WARN_IF(!spellCheckSelection)) {
return NS_ERROR_FAILURE;
}
return IsPointInSelection(spellCheckSelection, aNode, aOffset, newword);
return IsPointInSelection(*spellCheckSelection, aNode, aOffset, newword);
}
// mozInlineSpellChecker::ReplaceWord
@ -1049,9 +1045,7 @@ mozInlineSpellChecker::DidSplitNode(nsINode* aExistingRightNode,
if (!mIsListeningToEditActions) {
return;
}
nsIDOMNode* newLeftDOMNode =
aNewLeftNode ? aNewLeftNode->AsDOMNode() : nullptr;
SpellCheckBetweenNodes(newLeftDOMNode, 0, newLeftDOMNode, 0);
SpellCheckBetweenNodes(aNewLeftNode, 0, aNewLeftNode, 0);
}
void
@ -1061,7 +1055,7 @@ mozInlineSpellChecker::DidJoinNodes(nsINode& aLeftNode,
if (!mIsListeningToEditActions) {
return;
}
SpellCheckBetweenNodes(aRightNode.AsDOMNode(), 0, aRightNode.AsDOMNode(), 0);
SpellCheckBetweenNodes(&aRightNode, 0, &aRightNode, 0);
}
// mozInlineSpellChecker::MakeSpellCheckRange
@ -1076,8 +1070,8 @@ mozInlineSpellChecker::DidJoinNodes(nsINode& aLeftNode,
nsresult
mozInlineSpellChecker::MakeSpellCheckRange(
nsIDOMNode* aStartNode, int32_t aStartOffset,
nsIDOMNode* aEndNode, int32_t aEndOffset,
nsINode* aStartNode, int32_t aStartOffset,
nsINode* aEndNode, int32_t aEndOffset,
nsRange** aRange)
{
nsresult rv;
@ -1096,8 +1090,7 @@ mozInlineSpellChecker::MakeSpellCheckRange(
// possibly use full range of the editor
if (! aStartNode || ! aEndNode) {
nsCOMPtr<nsIDOMElement> domRootElement =
do_QueryInterface(mTextEditor->GetRoot());
Element* domRootElement = mTextEditor->GetRoot();
if (NS_WARN_IF(!domRootElement)) {
return NS_ERROR_FAILURE;
}
@ -1113,8 +1106,7 @@ mozInlineSpellChecker::MakeSpellCheckRange(
// length). The former is faster if we keep getting different nodes here...
//
// Let's do the thing which can't end up with bad O(N^2) behavior.
nsCOMPtr<nsINode> endNode = do_QueryInterface(aEndNode);
aEndOffset = endNode->ChildNodes()->Length();
aEndOffset = aEndNode->ChildNodes()->Length();
}
// sometimes we are are requested to check an empty range (possibly an empty
@ -1122,17 +1114,15 @@ mozInlineSpellChecker::MakeSpellCheckRange(
if (aStartNode == aEndNode && aStartOffset == aEndOffset)
return NS_OK;
nsCOMPtr<nsINode> startNode = do_QueryInterface(aStartNode);
nsCOMPtr<nsINode> endNode = do_QueryInterface(aEndNode);
if (aEndOffset) {
rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, aEndOffset);
rv = range->SetStartAndEnd(aStartNode, aStartOffset, aEndNode, aEndOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
uint32_t endOffset;
endNode = nsRange::GetContainerAndOffsetAfter(endNode, &endOffset);
rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, endOffset);
aEndNode = nsRange::GetContainerAndOffsetAfter(aEndNode, &endOffset);
rv = range->SetStartAndEnd(aStartNode, aStartOffset, aEndNode, endOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -1143,9 +1133,9 @@ mozInlineSpellChecker::MakeSpellCheckRange(
}
nsresult
mozInlineSpellChecker::SpellCheckBetweenNodes(nsIDOMNode *aStartNode,
mozInlineSpellChecker::SpellCheckBetweenNodes(nsINode* aStartNode,
int32_t aStartOffset,
nsIDOMNode *aEndNode,
nsINode* aEndNode,
int32_t aEndOffset)
{
RefPtr<nsRange> range;
@ -1630,19 +1620,18 @@ mozInlineSpellChecker::ResumeCheck(UniquePtr<mozInlineSpellStatus>&& aStatus)
// If there is no intersection, *aRange will be nullptr.
nsresult
mozInlineSpellChecker::IsPointInSelection(nsISelection *aSelection,
mozInlineSpellChecker::IsPointInSelection(Selection& aSelection,
nsIDOMNode *aNode,
int32_t aOffset,
nsIDOMRange **aRange)
{
*aRange = nullptr;
nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(aSelection));
nsTArray<nsRange*> ranges;
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
nsresult rv = privSel->GetRangesForIntervalArray(node, aOffset, node, aOffset,
true, &ranges);
nsresult rv = aSelection.GetRangesForIntervalArray(node, aOffset,
node, aOffset,
true, &ranges);
NS_ENSURE_SUCCESS(rv, rv);
if (ranges.Length() == 0)

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

@ -62,8 +62,10 @@ public:
int32_t mWordCount;
// what happened?
enum Operation { eOpChange, // for SpellCheckAfterChange except deleteSelection
eOpChangeDelete, // for SpellCheckAfterChange deleteSelection
enum Operation { eOpChange, // for SpellCheckAfterEditorChange except
// deleteSelection
eOpChangeDelete, // for SpellCheckAfterEditorChange with
// deleteSelection
eOpNavigation, // for HandleNavigationEvent
eOpSelection, // re-check all misspelled words
eOpResume }; // for resuming a previously started check
@ -201,9 +203,9 @@ public:
mozInlineSpellChecker();
// spell checks all of the words between two nodes
nsresult SpellCheckBetweenNodes(nsIDOMNode *aStartNode,
nsresult SpellCheckBetweenNodes(nsINode* aStartNode,
int32_t aStartOffset,
nsIDOMNode *aEndNode,
nsINode* aEndNode,
int32_t aEndOffset);
// examines the dom node in question and returns true if the inline spell
@ -211,10 +213,6 @@ public:
// or an e-mail signature...)
bool ShouldSpellCheckNode(mozilla::TextEditor* aTextEditor, nsINode *aNode);
nsresult SpellCheckAfterChange(nsIDOMNode* aCursorNode, int32_t aCursorOffset,
nsIDOMNode* aPreviousNode, int32_t aPreviousOffset,
nsISelection* aSpellCheckSelection);
// spell check the text contained within aRange, potentially scheduling
// another check in the future if the time threshold is reached
nsresult ScheduleSpellCheck(mozilla::UniquePtr<mozInlineSpellStatus>&& aStatus);
@ -227,7 +225,7 @@ public:
bool* aDoneChecking);
// helper routine to determine if a point is inside of the passed in selection.
nsresult IsPointInSelection(nsISelection *aSelection,
nsresult IsPointInSelection(mozilla::dom::Selection& aSelection,
nsIDOMNode *aNode,
int32_t aOffset,
nsIDOMRange **aRange);
@ -240,8 +238,8 @@ public:
nsRange* aRange);
bool SpellCheckSelectionIsFull() { return mNumWordsInSpellSelection >= mMaxNumWordsInSpellSelection; }
nsresult MakeSpellCheckRange(nsIDOMNode* aStartNode, int32_t aStartOffset,
nsIDOMNode* aEndNode, int32_t aEndOffset,
nsresult MakeSpellCheckRange(nsINode* aStartNode, int32_t aStartOffset,
nsINode* aEndNode, int32_t aEndOffset,
nsRange** aRange);
// DOM and editor event registration helper routines

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

@ -12,10 +12,7 @@
#include "nsDebug.h"
#include "nsAtom.h"
#include "nsComponentManagerUtils.h"
#include "nsIDOMElement.h"
#include "nsIDOMRange.h"
#include "nsIEditor.h"
#include "nsIDOMNode.h"
#include "nsUnicodeProperties.h"
#include "nsServiceManagerUtils.h"
#include "nsIContent.h"
@ -62,7 +59,6 @@ mozInlineSpellWordUtil::Init(TextEditor* aTextEditor)
if (NS_WARN_IF(!mDocument)) {
return NS_ERROR_FAILURE;
}
mDOMDocument = do_QueryInterface(mDocument);
// Find the root node for the editor. For contenteditable we'll need something
// cleverer here.
@ -242,13 +238,12 @@ mozInlineSpellWordUtil::MakeNodeOffsetRangeForWord(const RealWord& aWord,
// mozInlineSpellWordUtil::GetRangeForWord
nsresult
mozInlineSpellWordUtil::GetRangeForWord(nsIDOMNode* aWordNode,
mozInlineSpellWordUtil::GetRangeForWord(nsINode* aWordNode,
int32_t aWordOffset,
nsRange** aRange)
{
// Set our soft end and start
nsCOMPtr<nsINode> wordNode = do_QueryInterface(aWordNode);
NodeOffset pt = NodeOffset(wordNode, aWordOffset);
NodeOffset pt(aWordNode, aWordOffset);
if (!mSoftTextValid || pt != mSoftBegin || pt != mSoftEnd) {
InvalidateWords();
@ -335,8 +330,9 @@ mozInlineSpellWordUtil::MakeRange(NodeOffset aBegin, NodeOffset aEnd,
nsRange** aRange)
{
NS_ENSURE_ARG_POINTER(aBegin.mNode);
if (!mDOMDocument)
if (!mDocument) {
return NS_ERROR_NOT_INITIALIZED;
}
RefPtr<nsRange> range = new nsRange(aBegin.mNode);
nsresult rv = range->SetStartAndEnd(aBegin.mNode, aBegin.mOffset,

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

@ -6,8 +6,8 @@
#ifndef mozInlineSpellWordUtil_h
#define mozInlineSpellWordUtil_h
#include "mozilla/Attributes.h"
#include "nsCOMPtr.h"
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsString.h"
#include "nsTArray.h"
@ -88,7 +88,7 @@ public:
* 4. Call GetNextWord over and over until it returns false.
*/
class mozInlineSpellWordUtil
class MOZ_STACK_CLASS mozInlineSpellWordUtil
{
public:
mozInlineSpellWordUtil()
@ -113,7 +113,7 @@ public:
// THIS CHANGES THE CURRENT POSITION AND RANGE. It is designed to be called
// before you actually generate the range you are interested in and iterate
// the words in it.
nsresult GetRangeForWord(nsIDOMNode* aWordNode, int32_t aWordOffset,
nsresult GetRangeForWord(nsINode* aWordNode, int32_t aWordOffset,
nsRange** aRange);
// Convenience functions, object must be initialized
@ -131,14 +131,12 @@ public:
// so we can access characters directly.
static void NormalizeWord(nsAString& aWord);
nsIDOMDocument* GetDOMDocument() const { return mDOMDocument; }
nsIDocument* GetDocument() const { return mDocument; }
nsINode* GetRootNode() { return mRootNode; }
private:
// cached stuff for the editor, set by Init
nsCOMPtr<nsIDOMDocument> mDOMDocument;
nsCOMPtr<nsIDocument> mDocument;
// range to check, see SetPosition and SetEnd

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

@ -49,18 +49,9 @@ JITTEST_SANITIZER_ENV=MSAN_SYMBOLIZER_PATH='$(LLVM_SYMBOLIZER)'
endif
endif
check-style::
(cd $(topsrcdir) && $(PYTHON) $(topsrcdir)/config/check_spidermonkey_style.py);
check-masm::
(cd $(topsrcdir) && $(PYTHON) $(topsrcdir)/config/check_macroassembler_style.py);
check-js-msg::
(cd $(topsrcdir) && $(PYTHON) $(topsrcdir)/config/check_js_msg_encoding.py);
check-opcode::
(cd $(topsrcdir) && $(PYTHON) $(topsrcdir)/config/check_js_opcode.py);
check-jit-test::
$(JITTEST_SANITIZER_ENV) $(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/jit-test/jit_test.py \
--no-slow --no-progress --format=automation --jitflags=all \
@ -68,7 +59,7 @@ check-jit-test::
$(JITTEST_EXTRA_ARGS) \
$(DIST)/bin/$(JS_SHELL_NAME)$(BIN_SUFFIX) $(JITTEST_TEST_ARGS)
check:: check-style check-masm check-js-msg check-opcode
check:: check-js-msg
check-jstests:
$(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/tests/jstests.py \

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

@ -31,11 +31,14 @@ fn main() {
// can swap in instead and everything using a single malloc is
// good.
"--no-jemalloc",
// Don't try to clobber the output directory. Without
// this option, the build will fail because the directory
// already exists but wasn't created by autospider.
"--dep",
"--objdir", &out_dir,
variant])
.env("SOURCE", &js_src)
.env("PWD", &js_src)
.env("AUTOMATION", "1")
.stdout(Stdio::inherit())
.stderr(Stdio::inherit());
println!("Running command: {:?}", cmd);

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

@ -75,3 +75,15 @@ DIST_INSTALL = True
# with those in libxul.
if CONFIG['OS_TARGET'] == 'Linux':
LDFLAGS += ['-Wl,-version-script,symverscript']
# Run SpiderMonkey style checker after linking the static library. This avoids
# running the script for no-op builds.
GENERATED_FILES += ['spidermonkey_checks']
run_checks = GENERATED_FILES['spidermonkey_checks']
run_checks.script = '/config/run_spidermonkey_checks.py'
run_checks.inputs += [
'!%sjs_static.%s' % (CONFIG['LIB_PREFIX'], CONFIG['LIB_SUFFIX']),
'/config/check_spidermonkey_style.py',
'/config/check_macroassembler_style.py',
'/config/check_js_opcode.py'
]

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

@ -125,17 +125,16 @@ function getUnicodeExtensions(locale) {
* Parser for BCP 47 language tags.
*
* Returns null if |locale| can't be parsed as a Language-Tag. If the input is
* an irregular grandfathered language tag, the object
* a grandfathered language tag, the object
*
* {
* locale: locale.toLowerCase(),
* locale: locale (normalized to canonical form),
* grandfathered: true,
* }
*
* is returned. Otherwise the returned object has the following structure:
*
* {
* locale: locale.toLowerCase(),
* language: language subtag without extlang / undefined,
* extlang1: first extlang subtag / undefined,
* extlang2: second extlang subtag / undefined,
@ -147,13 +146,12 @@ function getUnicodeExtensions(locale) {
* privateuse: privateuse subtag / undefined,
* }
*
* All language tag subtags are returned in lower-case:
* All language tag subtags are returned in their normalized case:
*
* var langtag = parseLanguageTag("en-Latn-US");
* assertEq("en-latn-us", langtag.locale);
* var langtag = parseLanguageTag("en-latn-us");
* assertEq("en", langtag.language);
* assertEq("latn", langtag.script);
* assertEq("us", langtag.region);
* assertEq("Latn", langtag.script);
* assertEq("US", langtag.region);
*
* Spec: RFC 5646 section 2.1.
*/
@ -307,6 +305,12 @@ function parseLanguageTag(locale) {
// script = 4ALPHA ; ISO 15924 code
if (tokenLength === 4 && token === ALPHA) {
script = tokenStringLower();
// The first character of a script code needs to be capitalized.
// "hans" -> "Hans"
script = callFunction(std_String_toUpperCase, script[0]) +
Substring(script, 1, script.length - 1);
if (!nextToken())
return null;
}
@ -315,6 +319,10 @@ function parseLanguageTag(locale) {
// / 3DIGIT ; UN M.49 code
if ((tokenLength === 2 && token === ALPHA) || (tokenLength === 3 && token === DIGIT)) {
region = tokenStringLower();
// Region codes need to be in upper-case. "bu" -> "BU"
region = callFunction(std_String_toUpperCase, region);
if (!nextToken())
return null;
}
@ -417,12 +425,11 @@ function parseLanguageTag(locale) {
localeLowercase.length - privateuseStart);
}
// Return if the complete input was successfully parsed. That means it is
// either a langtag or privateuse-only language tag, or it is a regular
// grandfathered language tag.
if (token === NONE) {
// Return if the complete input was successfully parsed and it is not a
// regular grandfathered language tag. That means it is either a langtag
// or privateuse-only language tag
if (token === NONE && !hasOwn(localeLowercase, grandfatheredMappings)) {
return {
locale: localeLowercase,
language,
extlang1,
extlang2,
@ -443,76 +450,48 @@ function parseLanguageTag(locale) {
// For example we need to reject "i-ha\u212A" (U+212A KELVIN SIGN) even
// though its lower-case form "i-hak" matches a grandfathered language
// tag.
do {
while (token !== NONE) {
if (!nextToken())
return null;
} while (token !== NONE);
}
// grandfathered = irregular ; non-redundant tags registered
// / regular ; during the RFC 3066 era
switch (localeLowercase) {
#ifdef DEBUG
// regular = "art-lojban" ; these tags match the 'langtag'
// / "cel-gaulish" ; production, but their subtags
// / "no-bok" ; are not extended language
// / "no-nyn" ; or variant subtags: their meaning
// / "zh-guoyu" ; is defined by their registration
// / "zh-hakka" ; and all of these are deprecated
// / "zh-min" ; in favor of a more modern
// / "zh-min-nan" ; subtag or sequence of subtags
// / "zh-xiang"
case "art-lojban":
case "cel-gaulish":
case "no-bok":
case "no-nyn":
case "zh-guoyu":
case "zh-hakka":
case "zh-min":
case "zh-min-nan":
case "zh-xiang":
assert(false, "regular grandfathered tags should have been matched above");
#endif /* DEBUG */
// irregular = "en-GB-oed" ; irregular tags do not match
// / "i-ami" ; the 'langtag' production and
// / "i-bnn" ; would not otherwise be
// / "i-default" ; considered 'well-formed'
// / "i-enochian" ; These tags are all valid,
// / "i-hak" ; but most are deprecated
// / "i-klingon" ; in favor of more modern
// / "i-lux" ; subtags or subtag
// / "i-mingo" ; combination
// / "i-navajo"
// / "i-pwn"
// / "i-tao"
// / "i-tay"
// / "i-tsu"
// / "sgn-BE-FR"
// / "sgn-BE-NL"
// / "sgn-CH-DE"
case "en-gb-oed":
case "i-ami":
case "i-bnn":
case "i-default":
case "i-enochian":
case "i-hak":
case "i-klingon":
case "i-lux":
case "i-mingo":
case "i-navajo":
case "i-pwn":
case "i-tao":
case "i-tay":
case "i-tsu":
case "sgn-be-fr":
case "sgn-be-nl":
case "sgn-ch-de":
return { locale: localeLowercase, grandfathered: true };
default:
return null;
// irregular = "en-GB-oed" ; irregular tags do not match
// / "i-ami" ; the 'langtag' production and
// / "i-bnn" ; would not otherwise be
// / "i-default" ; considered 'well-formed'
// / "i-enochian" ; These tags are all valid,
// / "i-hak" ; but most are deprecated
// / "i-klingon" ; in favor of more modern
// / "i-lux" ; subtags or subtag
// / "i-mingo" ; combination
// / "i-navajo"
// / "i-pwn"
// / "i-tao"
// / "i-tay"
// / "i-tsu"
// / "sgn-BE-FR"
// / "sgn-BE-NL"
// / "sgn-CH-DE"
// regular = "art-lojban" ; these tags match the 'langtag'
// / "cel-gaulish" ; production, but their subtags
// / "no-bok" ; are not extended language
// / "no-nyn" ; or variant subtags: their meaning
// / "zh-guoyu" ; is defined by their registration
// / "zh-hakka" ; and all of these are deprecated
// / "zh-min" ; in favor of a more modern
// / "zh-min-nan" ; subtag or sequence of subtags
// / "zh-xiang"
if (hasOwn(localeLowercase, grandfatheredMappings)) {
return {
locale: grandfatheredMappings[localeLowercase],
grandfathered: true
};
}
return null;
#undef NONE
#undef ALPHA
#undef DIGIT
@ -560,16 +539,12 @@ function IsStructurallyValidLanguageTag(locale) {
function CanonicalizeLanguageTagFromObject(localeObj) {
assert(IsObject(localeObj), "CanonicalizeLanguageTagFromObject");
var {locale} = localeObj;
assert(locale === callFunction(std_String_toLowerCase, locale),
"expected lower-case form for locale string");
// Handle grandfathered language tags.
if (hasOwn("grandfathered", localeObj))
return localeObj.locale;
// Handle mappings for complete tags.
if (hasOwn(locale, langTagMappings))
return langTagMappings[locale];
assert(!hasOwn("grandfathered", localeObj),
"grandfathered tags should be mapped completely");
// Update mappings for complete tags.
updateLangTagMappings(localeObj);
var {
language,
@ -630,25 +605,25 @@ function CanonicalizeLanguageTagFromObject(localeObj) {
if (extlang3)
canonical += "-" + extlang3;
// No script replacements are currently present, so append as is.
if (script) {
// The first character of a script code needs to be capitalized.
// "hans" -> "Hans"
script = callFunction(std_String_toUpperCase, script[0]) +
Substring(script, 1, script.length - 1);
// No script replacements are currently present, so append as is.
assert(script.length === 4 &&
script ===
callFunction(std_String_toUpperCase, script[0]) +
callFunction(std_String_toLowerCase, Substring(script, 1, script.length - 1)),
"script must be [A-Z][a-z]{3}");
canonical += "-" + script;
}
if (region) {
// Region codes need to be in upper-case. "bu" -> "BU"
region = callFunction(std_String_toUpperCase, region);
// Replace deprecated subtags with their preferred values.
// "BU" -> "MM"
if (hasOwn(region, regionMappings))
region = regionMappings[region];
assert((2 <= region.length && region.length <= 3) &&
region === callFunction(std_String_toUpperCase, region),
"region must be [A-Z]{2} or [0-9]{3}");
canonical += "-" + region;
}
@ -733,9 +708,9 @@ function ValidateAndCanonicalizeLanguageTag(locale) {
// The language subtag is canonicalized to lower case.
locale = callFunction(std_String_toLowerCase, locale);
// langTagMappings doesn't contain any 2*3ALPHA keys, so we don't need
// to check for possible replacements in this map.
assert(!hasOwn(locale, langTagMappings), "langTagMappings contains no 2*3ALPHA mappings");
// updateLangTagMappings doesn't modify tags containing only
// |language| subtags, so we don't need to call it for possible
// replacements.
// Replace deprecated subtags with their preferred values.
locale = hasOwn(locale, languageMappings)

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

@ -1,9 +1,321 @@
// Generated by make_intl_data.py. DO NOT EDIT.
/* eslint-disable complexity */
// Mappings from complete tags to preferred values.
// Derived from IANA Language Subtag Registry, file date 2018-03-20.
// Derived from IANA Language Subtag Registry, file date 2018-03-30.
// https://www.iana.org/assignments/language-subtag-registry
var langTagMappings = {
function updateLangTagMappings(tag) {
assert(IsObject(tag), "tag is an object");
assert(!hasOwn("grandfathered", tag), "tag is not a grandfathered tag");
switch (tag.language) {
case "hy":
// hy-arevela -> hy
if (tag.variants.length >= 1 &&
callFunction(ArrayIndexOf, tag.variants, "arevela") > -1)
{
var newVariants = [];
for (var i = 0; i < tag.variants.length; i++) {
var variant = tag.variants[i];
if (variant === "arevela")
continue;
_DefineDataProperty(newVariants, newVariants.length, variant);
}
tag.variants = newVariants;
}
// hy-arevmda -> hyw
else if (tag.variants.length >= 1 &&
callFunction(ArrayIndexOf, tag.variants, "arevmda") > -1)
{
tag.language = "hyw";
var newVariants = [];
for (var i = 0; i < tag.variants.length; i++) {
var variant = tag.variants[i];
if (variant === "arevmda")
continue;
_DefineDataProperty(newVariants, newVariants.length, variant);
}
tag.variants = newVariants;
}
break;
case "ja":
// ja-Latn-hepburn-heploc -> ja-Latn-alalc97
if (tag.script === "Latn" &&
tag.variants.length >= 2 &&
callFunction(ArrayIndexOf, tag.variants, "hepburn") > -1 &&
callFunction(ArrayIndexOf, tag.variants, "heploc", callFunction(ArrayIndexOf, tag.variants, "hepburn") + 1) > -1)
{
var newVariants = [];
for (var i = 0; i < tag.variants.length; i++) {
var variant = tag.variants[i];
if (variant === "hepburn")
continue;
if (variant === "heploc")
continue;
_DefineDataProperty(newVariants, newVariants.length, variant);
}
if (callFunction(ArrayIndexOf, newVariants, "alalc97") < 0)
_DefineDataProperty(newVariants, newVariants.length, "alalc97");
tag.variants = newVariants;
}
break;
case "sgn":
// sgn-BR -> bzs
if (tag.region === "BR" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "bzs";
tag.region = undefined;
}
// sgn-CO -> csn
else if (tag.region === "CO" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "csn";
tag.region = undefined;
}
// sgn-DE -> gsg
else if (tag.region === "DE" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "gsg";
tag.region = undefined;
}
// sgn-DK -> dsl
else if (tag.region === "DK" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "dsl";
tag.region = undefined;
}
// sgn-ES -> ssp
else if (tag.region === "ES" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "ssp";
tag.region = undefined;
}
// sgn-FR -> fsl
else if (tag.region === "FR" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "fsl";
tag.region = undefined;
}
// sgn-GB -> bfi
else if (tag.region === "GB" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "bfi";
tag.region = undefined;
}
// sgn-GR -> gss
else if (tag.region === "GR" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "gss";
tag.region = undefined;
}
// sgn-IE -> isg
else if (tag.region === "IE" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "isg";
tag.region = undefined;
}
// sgn-IT -> ise
else if (tag.region === "IT" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "ise";
tag.region = undefined;
}
// sgn-JP -> jsl
else if (tag.region === "JP" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "jsl";
tag.region = undefined;
}
// sgn-MX -> mfs
else if (tag.region === "MX" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "mfs";
tag.region = undefined;
}
// sgn-NI -> ncs
else if (tag.region === "NI" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "ncs";
tag.region = undefined;
}
// sgn-NL -> dse
else if (tag.region === "NL" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "dse";
tag.region = undefined;
}
// sgn-NO -> nsl
else if (tag.region === "NO" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "nsl";
tag.region = undefined;
}
// sgn-PT -> psr
else if (tag.region === "PT" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "psr";
tag.region = undefined;
}
// sgn-SE -> swl
else if (tag.region === "SE" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "swl";
tag.region = undefined;
}
// sgn-US -> ase
else if (tag.region === "US" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "ase";
tag.region = undefined;
}
// sgn-ZA -> sfs
else if (tag.region === "ZA" &&
tag.extlang1 === undefined &&
tag.extlang2 === undefined &&
tag.extlang3 === undefined &&
tag.script === undefined &&
tag.variants.length === 0 &&
tag.extensions.length === 0 &&
tag.privateuse === undefined)
{
tag.language = "sfs";
tag.region = undefined;
}
break;
}
}
/* eslint-enable complexity */
// Mappings from grandfathered tags to preferred values.
// Derived from IANA Language Subtag Registry, file date 2018-03-30.
// https://www.iana.org/assignments/language-subtag-registry
var grandfatheredMappings = {
"art-lojban": "jbo",
"cel-gaulish": "cel-gaulish",
"en-gb-oed": "en-GB-oxendict",
@ -20,46 +332,20 @@ var langTagMappings = {
"i-tao": "tao",
"i-tay": "tay",
"i-tsu": "tsu",
"ja-latn-hepburn-heploc": "ja-Latn-alalc97",
"no-bok": "nb",
"no-nyn": "nn",
"sgn-be-fr": "sfb",
"sgn-be-nl": "vgt",
"sgn-br": "bzs",
"sgn-ch-de": "sgg",
"sgn-co": "csn",
"sgn-de": "gsg",
"sgn-dk": "dsl",
"sgn-es": "ssp",
"sgn-fr": "fsl",
"sgn-gb": "bfi",
"sgn-gr": "gss",
"sgn-ie": "isg",
"sgn-it": "ise",
"sgn-jp": "jsl",
"sgn-mx": "mfs",
"sgn-ni": "ncs",
"sgn-nl": "dse",
"sgn-no": "nsl",
"sgn-pt": "psr",
"sgn-se": "swl",
"sgn-us": "ase",
"sgn-za": "sfs",
"zh-cmn": "cmn",
"zh-cmn-hans": "cmn-Hans",
"zh-cmn-hant": "cmn-Hant",
"zh-gan": "gan",
"zh-guoyu": "cmn",
"zh-hakka": "hak",
"zh-min": "zh-min",
"zh-min-nan": "nan",
"zh-wuu": "wuu",
"zh-xiang": "hsn",
"zh-yue": "yue",
};
// Mappings from language subtags to preferred values.
// Derived from IANA Language Subtag Registry, file date 2018-03-20.
// Derived from IANA Language Subtag Registry, file date 2018-03-30.
// https://www.iana.org/assignments/language-subtag-registry
var languageMappings = {
"aam": "aas",
@ -143,7 +429,7 @@ var languageMappings = {
};
// Mappings from region subtags to preferred values.
// Derived from IANA Language Subtag Registry, file date 2018-03-20.
// Derived from IANA Language Subtag Registry, file date 2018-03-30.
// https://www.iana.org/assignments/language-subtag-registry
var regionMappings = {
"BU": "MM",
@ -158,7 +444,7 @@ var regionMappings = {
// All current deprecated extlang subtags have the form `<prefix>-<extlang>`
// and their preferred value is exactly equal to `<extlang>`. So each key in
// extlangMappings acts both as the extlang subtag and its preferred value.
// Derived from IANA Language Subtag Registry, file date 2018-03-20.
// Derived from IANA Language Subtag Registry, file date 2018-03-30.
// https://www.iana.org/assignments/language-subtag-registry
var extlangMappings = {
"aao": "ar",

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

@ -69,30 +69,34 @@ def readRegistryRecord(registry):
yield record
return
def readRegistry(registry):
""" Reads IANA Language Subtag Registry and extracts information for Intl.js.
Information extracted:
- langTagMappings: mappings from complete language tags to preferred
- grandfatheredMappings: mappings from grandfathered tags to preferred
complete language tags
- redundantMappings: mappings from redundant tags to preferred complete
language tags
- languageMappings: mappings from language subtags to preferred subtags
- regionMappings: mappings from region subtags to preferred subtags
- variantMappings: mappings from complete language tags to preferred
complete language tags
- extlangMappings: mappings from extlang subtags to preferred subtags,
with prefix to be removed
Returns these four mappings as dictionaries, along with the registry's
Returns these six mappings as dictionaries, along with the registry's
file date.
We also check that extlang mappings don't generate preferred values
which in turn are subject to language subtag mappings, so that
CanonicalizeLanguageTag can process subtags sequentially.
"""
langTagMappings = {}
grandfatheredMappings = {}
redundantMappings = {}
languageMappings = {}
regionMappings = {}
variantMappings = {}
extlangMappings = {}
languageSubtags = set()
extlangSubtags = set()
extlangSubtags = []
for record in readRegistryRecord(registry):
if "File-Date" in record:
@ -103,23 +107,22 @@ def readRegistry(registry):
# Grandfathered tags don't use standard syntax, so
# CanonicalizeLanguageTag expects the mapping table to provide
# the final form for all.
# For langTagMappings, keys must be in lower case; values in
# For grandfatheredMappings, keys must be in lower case; values in
# the case used in the registry.
tag = record["Tag"]
if "Preferred-Value" in record:
langTagMappings[tag.lower()] = record["Preferred-Value"]
grandfatheredMappings[tag.lower()] = record["Preferred-Value"]
else:
langTagMappings[tag.lower()] = tag
grandfatheredMappings[tag.lower()] = tag
elif record["Type"] == "redundant":
# For langTagMappings, keys must be in lower case; values in
# the case used in the registry.
# For redundantMappings, keys and values must be in the case used
# in the registry.
if "Preferred-Value" in record:
langTagMappings[record["Tag"].lower()] = record["Preferred-Value"]
redundantMappings[record["Tag"]] = record["Preferred-Value"]
elif record["Type"] == "language":
# For languageMappings, keys and values must be in the case used
# in the registry.
subtag = record["Subtag"]
languageSubtags.add(subtag)
if "Preferred-Value" in record:
# The 'Prefix' field is not allowed for language records.
# https://tools.ietf.org/html/rfc5646#section-3.1.2
@ -139,21 +142,19 @@ def readRegistry(registry):
# The registry currently doesn't contain mappings for scripts.
raise Exception("Unexpected mapping for script subtags")
elif record["Type"] == "variant":
subtag = record["Subtag"]
# For variantMappings, keys and values must be in the case used in
# the registry.
if "Preferred-Value" in record:
if subtag == "heploc":
# The entry for heploc is unique in its complexity; handle
# it as special case below.
continue
# The registry currently doesn't contain mappings for variants,
# except for heploc which is already handled above.
raise Exception("Unexpected mapping for variant subtags")
if "Prefix" not in record:
raise Exception("Unexpected mapping for variant subtags")
tag = "{}-{}".format(record["Prefix"], record["Subtag"])
variantMappings[tag] = record["Preferred-Value"]
elif record["Type"] == "extlang":
# For extlangMappings, keys must be in the case used in the
# registry; values are records with the preferred value and the
# prefix to be removed.
subtag = record["Subtag"]
extlangSubtags.add(subtag)
extlangSubtags.append(subtag)
if "Preferred-Value" in record:
preferred = record["Preferred-Value"]
# The 'Preferred-Value' and 'Subtag' fields MUST be identical.
@ -173,57 +174,349 @@ def readRegistry(registry):
raise Exception("Conflict: extlang with lang mapping: " + extlang)
# Special case for heploc.
langTagMappings["ja-latn-hepburn-heploc"] = "ja-Latn-alalc97"
assert variantMappings["ja-Latn-hepburn-heploc"] == "alalc97"
variantMappings["ja-Latn-hepburn-heploc"] = "ja-Latn-alalc97"
# ValidateAndCanonicalizeLanguageTag in CommonFunctions.js expects
# langTagMappings contains no 2*3ALPHA.
assert all(len(lang) > 3 for lang in langTagMappings.iterkeys())
# redundantMappings contains no 2*3ALPHA.
assert all(len(lang) > 3 for lang in redundantMappings.iterkeys())
return {"fileDate": fileDate,
"langTagMappings": langTagMappings,
"grandfatheredMappings": grandfatheredMappings,
"redundantMappings": redundantMappings,
"languageMappings": languageMappings,
"regionMappings": regionMappings,
"variantMappings": variantMappings,
"extlangMappings": extlangMappings}
def writeMappingsVar(intlData, dict, name, description, fileDate, url):
""" Writes a variable definition with a mapping table to file intlData.
Writes the contents of dictionary dict to file intlData with the given
variable name and a comment with description, fileDate, and URL.
"""
intlData.write("\n")
def writeMappingHeader(println, description, fileDate, url):
if type(description) is not list:
description = [description]
for desc in description:
intlData.write("// {0}\n".format(desc))
intlData.write("// Derived from IANA Language Subtag Registry, file date {0}.\n".format(fileDate))
intlData.write("// {0}\n".format(url))
intlData.write("var {0} = {{\n".format(name))
keys = sorted(dict)
for key in keys:
if isinstance(dict[key], basestring):
value = '"{0}"'.format(dict[key])
println(u"// {0}".format(desc))
println(u"// Derived from IANA Language Subtag Registry, file date {0}.".format(fileDate))
println(u"// {0}".format(url))
def writeMappingsVar(println, mapping, name, description, fileDate, url):
""" Writes a variable definition with a mapping table.
Writes the contents of dictionary |mapping| through the |println|
function with the given variable name and a comment with description,
fileDate, and URL.
"""
println(u"")
writeMappingHeader(println, description, fileDate, url)
println(u"var {0} = {{".format(name))
for key in sorted(mapping):
if isinstance(mapping[key], basestring):
value = '"{0}"'.format(mapping[key])
else:
preferred = dict[key]["preferred"]
prefix = dict[key]["prefix"]
preferred = mapping[key]["preferred"]
prefix = mapping[key]["prefix"]
if key != preferred:
raise Exception("Expected '{0}' matches preferred locale '{1}'".format(key, preferred))
value = '"{0}"'.format(prefix)
intlData.write(' "{0}": {1},\n'.format(key, value))
intlData.write("};\n")
println(u' "{0}": {1},'.format(key, value))
println(u"};")
def writeMappingsFunction(println, variantMappings, redundantMappings, extlangMappings, description, fileDate, url):
""" Writes a function definition which performs language tag mapping.
def writeLanguageTagData(intlData, fileDate, url, langTagMappings, languageMappings,
regionMappings, extlangMappings):
Processes the contents of dictionaries |variantMappings| and
|redundantMappings| through the |println| function with the given
function name and a comment with description, fileDate, and URL.
"""
class Subtag:
Language, ExtLang, Script, Region, Variant = range(5)
Invalid = -1
def splitSubtags(tag):
seenLanguage = False
for subtag in tag.split("-"):
# language = 2*3ALPHA / 4ALPHA / 5*8ALPHA
if len(subtag) in range(2, 8+1) and subtag.isalpha() and not seenLanguage:
seenLanguage = True
kind = Subtag.Language
# extlang = 3ALPHA
elif len(subtag) == 3 and subtag.isalpha() and seenLanguage:
kind = Subtag.ExtLang
# script = 4ALPHA
elif len(subtag) == 4 and subtag.isalpha():
kind = Subtag.Script
# region = 2ALPHA / 3DIGIT
elif ((len(subtag) == 2 and subtag.isalpha()) or
(len(subtag) == 3 and subtag.isdigit())):
kind = Subtag.Region
# variant = 5*8alphanum / (DIGIT 3alphanum)
elif ((len(subtag) in range(5, 8+1) and subtag.isalnum()) or
(len(subtag) == 4 and subtag[0].isdigit() and subtag[1:].isalnum())):
kind = Subtag.Variant
else:
assert False, "unexpected language tag '{}'".format(key)
yield (kind, subtag)
def language(tag):
(kind, subtag) = next(splitSubtags(tag))
assert kind == Subtag.Language
return subtag
def variants(tag):
return [v for (k, v) in splitSubtags(tag) if k == Subtag.Variant]
def emitCompare(tag, preferred, isFirstLanguageTag):
def println_indent(level, *args):
println(u" " * (4 * level - 1), *args)
println2 = partial(println_indent, 2)
println3 = partial(println_indent, 3)
def maybeNext(it):
dummy = (Subtag.Invalid, "")
return next(it, dummy)
# Add a comment for the language tag mapping.
println2(u"// {} -> {}".format(tag, preferred))
# Compare the input language tag with the current language tag.
cond = []
extlangIndex = 1
lastVariant = None
for (kind, subtag) in splitSubtags(tag):
if kind == Subtag.Language:
continue
if kind == Subtag.ExtLang:
assert extlangIndex in [1, 2, 3],\
"Language-Tag permits no more than three extlang subtags"
cond.append('tag.extlang{} === "{}"'.format(extlangIndex, subtag))
extlangIndex += 1
elif kind == Subtag.Script:
cond.append('tag.script === "{}"'.format(subtag))
elif kind == Subtag.Region:
cond.append('tag.region === "{}"'.format(subtag))
else:
assert kind == Subtag.Variant
if lastVariant is None:
cond.append("tag.variants.length >= {}".format(len(variants(tag))))
cond.append('callFunction(ArrayIndexOf, tag.variants, "{}") > -1'.format(subtag))
else:
cond.append('callFunction(ArrayIndexOf, tag.variants, "{}", callFunction(ArrayIndexOf, tag.variants, "{}") + 1) > -1'.format(subtag, lastVariant))
lastVariant = subtag
# Require exact matches for redundant language tags.
if tag in redundantMappings:
tag_it = splitSubtags(tag)
tag_next = partial(maybeNext, tag_it)
(tag_kind, _) = tag_next()
assert tag_kind == Subtag.Language
(tag_kind, _) = tag_next()
subtags = ([(Subtag.ExtLang, "extlang{}".format(i)) for i in range(1, 3+1)] +
[(Subtag.Script, "script"), (Subtag.Region, "region")])
for kind, prop_name in subtags:
if tag_kind == kind:
(tag_kind, _) = tag_next()
else:
cond.append("tag.{} === undefined".format(prop_name))
cond.append("tag.variants.length === {}".format(len(variants(tag))))
while tag_kind == Subtag.Variant:
(tag_kind, _) = tag_next()
cond.append("tag.extensions.length === 0")
cond.append("tag.privateuse === undefined")
assert list(tag_it) == [], "unhandled tag subtags"
# Emit either:
#
# if (cond) {
#
# or:
#
# if (cond_1 &&
# cond_2 &&
# ...
# cond_n)
# {
#
# depending on the number of conditions.
ifOrElseIf = "if" if isFirstLanguageTag else "else if"
assert len(cond) > 0, "expect at least one subtag condition"
if len(cond) == 1:
println2(u"{} ({}) {{".format(ifOrElseIf, cond[0]))
else:
println2(u"{} ({} &&".format(ifOrElseIf, cond[0]))
for c in cond[1:-1]:
println2(u"{}{} &&".format(" " * (len(ifOrElseIf) + 2), c))
println2(u"{}{})".format(" " * (len(ifOrElseIf) + 2), cond[-1]))
println2(u"{")
# Iterate over all subtags of |tag| and |preferred| and update |tag|
# with |preferred| in the process. |tag| is modified in-place to use
# the preferred values.
tag_it = splitSubtags(tag)
tag_next = partial(maybeNext, tag_it)
(tag_kind, tag_subtag) = tag_next()
preferred_it = splitSubtags(preferred)
preferred_next = partial(maybeNext, preferred_it)
(preferred_kind, preferred_subtag) = preferred_next()
# Update the language subtag.
assert tag_kind == Subtag.Language and preferred_kind == Subtag.Language
if tag_subtag != preferred_subtag:
println3(u'tag.language = "{}";'.format(preferred_subtag))
(tag_kind, tag_subtag) = tag_next()
(preferred_kind, preferred_subtag) = preferred_next()
# Remove any extlang subtags per RFC 5646, 4.5:
# 'The canonical form contains no 'extlang' subtags.'
# https://tools.ietf.org/html/rfc5646#section-4.5
assert preferred_kind != Subtag.ExtLang
extlangIndex = 1
while tag_kind == Subtag.ExtLang:
assert extlangIndex in [1, 2, 3],\
"Language-Tag permits no more than three extlang subtags"
println3(u"tag.extlang{} = undefined;".format(extlangIndex))
extlangIndex += 1
(tag_kind, tag_subtag) = tag_next()
# Update the script and region subtags.
for kind, prop_name in [(Subtag.Script, "script"), (Subtag.Region, "region")]:
if tag_kind == kind and preferred_kind == kind:
if tag_subtag != preferred_subtag:
println3(u'tag.{} = "{}";'.format(prop_name, preferred_subtag))
(tag_kind, tag_subtag) = tag_next()
(preferred_kind, preferred_subtag) = preferred_next()
elif tag_kind == kind:
println3(u"tag.{} = undefined;".format(prop_name))
(tag_kind, tag_subtag) = tag_next()
elif preferred_kind == kind:
println3(u'tag.{} = "{}";'.format(prop_name, preferred_subtag))
(preferred_kind, preferred_subtag) = preferred_next()
# Update variant subtags.
if tag_kind == Subtag.Variant or preferred_kind == Subtag.Variant:
# JS doesn't provide an easy way to remove elements from an array
# which doesn't trigger Symbol.species, so we need to create a new
# array and copy all elements.
println3(u"var newVariants = [];")
# Copy all variant subtags, ignoring those which should be removed.
println3(u"for (var i = 0; i < tag.variants.length; i++) {")
println3(u" var variant = tag.variants[i];")
while tag_kind == Subtag.Variant:
println3(u' if (variant === "{}")'.format(tag_subtag))
println3(u" continue;")
(tag_kind, tag_subtag) = tag_next()
println3(u" _DefineDataProperty(newVariants, newVariants.length, variant);")
println3(u"}")
# Add the new variants, unless already present.
while preferred_kind == Subtag.Variant:
println3(u'if (callFunction(ArrayIndexOf, newVariants, "{}") < 0)'.format(preferred_subtag))
println3(u' _DefineDataProperty(newVariants, newVariants.length, "{}");'.format(preferred_subtag))
(preferred_kind, preferred_subtag) = preferred_next()
# Update the property.
println3(u"tag.variants = newVariants;")
# Ensure both language tags were completely processed.
assert list(tag_it) == [], "unhandled tag subtags"
assert list(preferred_it) == [], "unhandled preferred subtags"
println2(u"}")
# Remove mappings for redundant language tags which are from our point of
# view, wait for it, redundant, because there is an equivalent extlang
# mapping.
#
# For example this entry for the redundant tag "zh-cmn":
#
# Type: redundant
# Tag: zh-cmn
# Preferred-Value: cmn
#
# Can also be expressed through the extlang mapping for "cmn":
#
# Type: extlang
# Subtag: cmn
# Preferred-Value: cmn
# Prefix: zh
#
def hasExtlangMapping(tag, preferred):
tag_it = splitSubtags(tag)
(_, tag_lang) = next(tag_it)
(tag_kind, tag_extlang) = next(tag_it)
preferred_it = splitSubtags(preferred)
(_, preferred_lang) = next(preferred_it)
# Return true if the mapping is for an extlang language and the extlang
# mapping table contains an equivalent entry and any trailing elements,
# if present, are the same.
return (tag_kind == Subtag.ExtLang and
(tag_extlang, {"preferred": preferred_lang, "prefix": tag_lang}) in extlangMappings.items() and
list(tag_it) == list(preferred_it))
# Create a single mapping for variant and redundant tags, ignoring the
# entries which are also covered through extlang mappings.
langTagMappings = {tag: preferred
for mapping in [variantMappings, redundantMappings]
for (tag, preferred) in mapping.items()
if not hasExtlangMapping(tag, preferred)}
println(u"")
println(u"/* eslint-disable complexity */")
writeMappingHeader(println, description, fileDate, url)
println(u"function updateLangTagMappings(tag) {")
println(u' assert(IsObject(tag), "tag is an object");')
println(u' assert(!hasOwn("grandfathered", tag), "tag is not a grandfathered tag");')
println(u"")
# Switch on the language subtag.
println(u" switch (tag.language) {")
for lang in sorted(set(language(tag) for tag in langTagMappings)):
println(u' case "{}":'.format(lang))
isFirstLanguageTag = True
for tag in sorted(tag for tag in langTagMappings if language(tag) == lang):
assert not isinstance(langTagMappings[tag], dict),\
"only supports complete language tags"
emitCompare(tag, langTagMappings[tag], isFirstLanguageTag)
isFirstLanguageTag = False
println(u" break;")
println(u" }")
println(u"}")
println(u"/* eslint-enable complexity */")
def writeLanguageTagData(println, data, url):
""" Writes the language tag data to the Intl data file. """
writeMappingsVar(intlData, langTagMappings, "langTagMappings",
"Mappings from complete tags to preferred values.", fileDate, url)
writeMappingsVar(intlData, languageMappings, "languageMappings",
fileDate = data["fileDate"]
grandfatheredMappings = data["grandfatheredMappings"]
redundantMappings = data["redundantMappings"]
languageMappings = data["languageMappings"]
regionMappings = data["regionMappings"]
variantMappings = data["variantMappings"]
extlangMappings = data["extlangMappings"]
writeMappingsFunction(println, variantMappings, redundantMappings, extlangMappings,
"Mappings from complete tags to preferred values.", fileDate, url)
writeMappingsVar(println, grandfatheredMappings, "grandfatheredMappings",
"Mappings from grandfathered tags to preferred values.", fileDate, url)
writeMappingsVar(println, languageMappings, "languageMappings",
"Mappings from language subtags to preferred values.", fileDate, url)
writeMappingsVar(intlData, regionMappings, "regionMappings",
writeMappingsVar(println, regionMappings, "regionMappings",
"Mappings from region subtags to preferred values.", fileDate, url)
writeMappingsVar(intlData, extlangMappings, "extlangMappings",
writeMappingsVar(println, extlangMappings, "extlangMappings",
["Mappings from extlang subtags to preferred values.",
"All current deprecated extlang subtags have the form `<prefix>-<extlang>`",
"and their preferred value is exactly equal to `<extlang>`. So each key in",
@ -256,17 +549,13 @@ def updateLangTags(args):
print("Processing IANA Language Subtag Registry...")
with closing(registry) as reg:
data = readRegistry(reg)
fileDate = data["fileDate"]
langTagMappings = data["langTagMappings"]
languageMappings = data["languageMappings"]
regionMappings = data["regionMappings"]
extlangMappings = data["extlangMappings"]
print("Writing Intl data...")
with codecs.open(out, "w", encoding="utf-8") as intlData:
intlData.write("// Generated by make_intl_data.py. DO NOT EDIT.\n")
writeLanguageTagData(intlData, fileDate, url, langTagMappings, languageMappings,
regionMappings, extlangMappings)
with io.open(out, mode="w", encoding="utf-8", newline="") as f:
println = partial(print, file=f)
println(u"// Generated by make_intl_data.py. DO NOT EDIT.")
writeLanguageTagData(println, data, url)
def flines(filepath, encoding="utf-8"):
""" Open filepath and iterate over its content. """
@ -746,11 +1035,11 @@ def processTimeZones(tzdataDir, icuDir, icuTzDir, version, ignoreBackzone, ignor
println(u"// Format:")
println(u'// "LinkName", "Target" // ICU-Target [time zone file]')
println(u"struct LinkAndTarget");
println(u"{");
println(u" const char* const link;");
println(u" const char* const target;");
println(u"};");
println(u"struct LinkAndTarget")
println(u"{")
println(u" const char* const link;")
println(u" const char* const target;")
println(u"};")
println(u"")
println(u"const LinkAndTarget ianaLinksCanonicalizedDifferentlyByICU[] = {")
for (zone, target, icuTarget) in incorrectLinks:

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

@ -477,11 +477,8 @@ if use_minidump:
# first failed status.
results = []
# 'checks' is a superset of 'check-style'.
if 'checks' in test_suites:
results.append(run_test_command([MAKE, 'check']))
elif 'check-style' in test_suites:
results.append(run_test_command([MAKE, 'check-style']))
if 'jittest' in test_suites:
results.append(run_test_command([MAKE, 'check-jit-test']))

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

@ -3,8 +3,5 @@
"debug": true,
"skip-tests": {
"all": ["jstests", "jittest", "checks"]
},
"extra-tests": {
"all": ["check-style"]
}
}

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

@ -244,15 +244,17 @@ GCRuntime::tryNewTenuredThing(JSContext* cx, AllocKind kind, size_t thingSize)
// chunks available it may also allocate new memory directly.
t = reinterpret_cast<T*>(refillFreeListFromAnyThread(cx, kind));
if (MOZ_UNLIKELY(!t && allowGC && !cx->helperThread())) {
// We have no memory available for a new chunk; perform an
// all-compartments, non-incremental, shrinking GC and wait for
// sweeping to finish.
JS::PrepareForFullGC(cx);
cx->runtime()->gc.gc(GC_SHRINK, JS::gcreason::LAST_DITCH);
cx->runtime()->gc.waitBackgroundSweepOrAllocEnd();
if (MOZ_UNLIKELY(!t && allowGC)) {
if (!cx->helperThread()) {
// We have no memory available for a new chunk; perform an
// all-compartments, non-incremental, shrinking GC and wait for
// sweeping to finish.
JS::PrepareForFullGC(cx);
cx->runtime()->gc.gc(GC_SHRINK, JS::gcreason::LAST_DITCH);
cx->runtime()->gc.waitBackgroundSweepOrAllocEnd();
t = tryNewTenuredThing<T, NoGC>(cx, kind, thingSize);
t = tryNewTenuredThing<T, NoGC>(cx, kind, thingSize);
}
if (!t)
ReportOutOfMemory(cx);
}

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

@ -26,6 +26,10 @@ Zone * const Zone::NotOnList = reinterpret_cast<Zone*>(1);
JS::Zone::Zone(JSRuntime* rt)
: JS::shadow::Zone(rt, &rt->gc.marker),
// Note: don't use |this| before initializing helperThreadUse_!
// ProtectedData checks in CheckZone::check may read this field.
helperThreadUse_(HelperThreadUse::None),
helperThreadOwnerContext_(nullptr),
debuggers(this, nullptr),
uniqueIds_(this),
suppressAllocationMetadataBuilder(this, false),
@ -54,8 +58,6 @@ JS::Zone::Zone(JSRuntime* rt)
nurseryShapes_(this),
data(this, nullptr),
isSystem(this, false),
helperThreadOwnerContext_(nullptr),
helperThreadUse(HelperThreadUse::None),
#ifdef DEBUG
gcLastSweepGroupIndex(this, 0),
#endif
@ -78,7 +80,7 @@ JS::Zone::Zone(JSRuntime* rt)
Zone::~Zone()
{
MOZ_ASSERT(helperThreadUse == HelperThreadUse::None);
MOZ_ASSERT(helperThreadUse_ == HelperThreadUse::None);
JSRuntime* rt = runtimeFromAnyThread();
if (this == rt->gc.systemZone)

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

@ -151,6 +151,44 @@ struct Zone : public JS::shadow::Zone,
MOZ_MUST_USE bool init(bool isSystem);
void destroy(js::FreeOp *fop);
private:
enum class HelperThreadUse : uint32_t {
None,
Pending,
Active
};
mozilla::Atomic<HelperThreadUse> helperThreadUse_;
// The helper thread context with exclusive access to this zone, if
// usedByHelperThread(), or nullptr when on the main thread.
js::UnprotectedData<JSContext*> helperThreadOwnerContext_;
public:
bool ownedByCurrentHelperThread();
void setHelperThreadOwnerContext(JSContext* cx);
// Whether this zone was created for use by a helper thread.
bool createdForHelperThread() const {
return helperThreadUse_ != HelperThreadUse::None;
}
// Whether this zone is currently in use by a helper thread.
bool usedByHelperThread() {
MOZ_ASSERT_IF(isAtomsZone(), helperThreadUse_ == HelperThreadUse::None);
return helperThreadUse_ == HelperThreadUse::Active;
}
void setCreatedForHelperThread() {
MOZ_ASSERT(helperThreadUse_ == HelperThreadUse::None);
helperThreadUse_ = HelperThreadUse::Pending;
}
void setUsedByHelperThread() {
MOZ_ASSERT(helperThreadUse_ == HelperThreadUse::Pending);
helperThreadUse_ = HelperThreadUse::Active;
}
void clearUsedByHelperThread() {
MOZ_ASSERT(helperThreadUse_ != HelperThreadUse::None);
helperThreadUse_ = HelperThreadUse::None;
}
void findOutgoingEdges(js::gc::ZoneComponentFinder& finder);
void discardJitCode(js::FreeOp* fop, bool discardBaselineCode = true);
@ -513,48 +551,6 @@ struct Zone : public JS::shadow::Zone,
js::ZoneData<bool> isSystem;
private:
// The helper thread context with exclusive access to this zone, if
// usedByHelperThread(), or nullptr when on the main thread.
js::UnprotectedData<JSContext*> helperThreadOwnerContext_;
public:
bool ownedByCurrentHelperThread();
void setHelperThreadOwnerContext(JSContext* cx);
private:
enum class HelperThreadUse : uint32_t
{
None,
Pending,
Active
};
mozilla::Atomic<HelperThreadUse> helperThreadUse;
public:
// Whether this zone was created for use by a helper thread.
bool createdForHelperThread() const {
return helperThreadUse != HelperThreadUse::None;
}
// Whether this zone is currently in use by a helper thread.
bool usedByHelperThread() {
MOZ_ASSERT_IF(isAtomsZone(), helperThreadUse == HelperThreadUse::None);
return helperThreadUse == HelperThreadUse::Active;
}
void setCreatedForHelperThread() {
MOZ_ASSERT(helperThreadUse == HelperThreadUse::None);
helperThreadUse = HelperThreadUse::Pending;
}
void setUsedByHelperThread() {
MOZ_ASSERT(helperThreadUse == HelperThreadUse::Pending);
helperThreadUse = HelperThreadUse::Active;
}
void clearUsedByHelperThread() {
MOZ_ASSERT(helperThreadUse != HelperThreadUse::None);
helperThreadUse = HelperThreadUse::None;
}
#ifdef DEBUG
js::ZoneData<unsigned> gcLastSweepGroupIndex;
#endif

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

@ -330,7 +330,7 @@ MacroAssemblerMIPS64::ma_dror(Register rd, Register rt, Register shift)
void
MacroAssemblerMIPS64::ma_drol(Register rd, Register rt, Register shift)
{
ma_negu(ScratchRegister, shift);
as_dsubu(ScratchRegister, zero, shift);
as_drotrv(rd, rt, ScratchRegister);
}

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

@ -36,6 +36,7 @@
#include "mozilla/MathAlgorithms.h"
#include <float.h>
#include <limits>
#include "jit/AtomicOperations.h"
#include "jit/mips64/Assembler-mips64.h"
@ -1557,6 +1558,7 @@ Simulator::testFCSRBit(uint32_t cc)
// Sets the rounding error codes in FCSR based on the result of the rounding.
// Returns true if the operation was invalid.
template <typename T>
bool
Simulator::setFCSRRoundError(double original, double rounded)
{
@ -1584,7 +1586,9 @@ Simulator::setFCSRRoundError(double original, double rounded)
ret = true;
}
if (rounded > INT_MAX || rounded < INT_MIN) {
if ((long double)rounded > (long double)std::numeric_limits<T>::max() ||
(long double)rounded < (long double)std::numeric_limits<T>::min())
{
setFCSRBit(kFCSROverflowFlagBit, true);
setFCSRBit(kFCSROverflowCauseBit, true);
// The reference is not really clear but it seems this is required:
@ -2115,19 +2119,19 @@ typedef int32_t (*Prototype_Int_GeneralGeneralInt64Int64)(int64_t arg0, int64_t
int64_t arg3);
typedef double (*Prototype_Double_None)();
typedef double (*Prototype_Double_Double)(double arg0);
typedef double (*Prototype_Double_Int)(int32_t arg0);
typedef int32_t (*Prototype_Int_Double)(double arg0);
typedef int32_t (*Prototype_Int_DoubleIntInt)(double arg0, int32_t arg1, int32_t arg2);
typedef int32_t (*Prototype_Int_IntDoubleIntInt)(int32_t arg0, double arg1, int32_t arg2,
int32_t arg3);
typedef double (*Prototype_Double_Int)(int64_t arg0);
typedef int64_t (*Prototype_Int_Double)(double arg0);
typedef int64_t (*Prototype_Int_DoubleIntInt)(double arg0, int64_t arg1, int64_t arg2);
typedef int64_t (*Prototype_Int_IntDoubleIntInt)(int64_t arg0, double arg1, int64_t arg2,
int64_t arg3);
typedef float (*Prototype_Float32_Float32)(float arg0);
typedef float (*Prototype_Float32_Float32Float32)(float arg0, float arg1);
typedef float (*Prototype_Float32_IntInt)(int32_t arg0, int32_t arg1);
typedef float (*Prototype_Float32_IntInt)(int64_t arg0, int64_t arg1);
typedef double (*Prototype_Double_DoubleInt)(double arg0, int32_t arg1);
typedef double (*Prototype_Double_IntDouble)(int32_t arg0, double arg1);
typedef double (*Prototype_Double_DoubleInt)(double arg0, int64_t arg1);
typedef double (*Prototype_Double_IntDouble)(int64_t arg0, double arg1);
typedef double (*Prototype_Double_DoubleDouble)(double arg0, double arg1);
typedef int32_t (*Prototype_Int_IntDouble)(int32_t arg0, double arg1);
typedef int64_t (*Prototype_Int_IntDouble)(int64_t arg0, double arg1);
typedef double (*Prototype_Double_DoubleDoubleDouble)(double arg0, double arg1, double arg2);
typedef double (*Prototype_Double_DoubleDoubleDoubleDouble)(double arg0, double arg1,
@ -2190,9 +2194,8 @@ Simulator::softwareInterrupt(SimInstruction* instr)
case Args_General3: {
Prototype_General3 target = reinterpret_cast<Prototype_General3>(external);
int64_t result = target(arg0, arg1, arg2);
if(external == intptr_t(&js::wasm::Instance::wake)) {
if (external == intptr_t(&js::wasm::Instance::wake))
result = int32_t(result);
}
setCallResult(result);
break;
}
@ -2238,36 +2241,42 @@ Simulator::softwareInterrupt(SimInstruction* instr)
case Args_Int_Double: {
double dval0 = getFpuRegisterDouble(12);
Prototype_Int_Double target = reinterpret_cast<Prototype_Int_Double>(external);
int32_t res = target(dval0);
setRegister(v0, res);
int64_t result = target(dval0);
if (external == intptr_t((int32_t(*)(double))JS::ToInt32))
result = int32_t(result);
setRegister(v0, result);
break;
}
case Args_Int_GeneralGeneralGeneralInt64: {
Prototype_Int_GeneralGeneralGeneralInt64 target =
reinterpret_cast<Prototype_Int_GeneralGeneralGeneralInt64>(external);
int32_t res = target(arg0, arg1, arg2, arg3);
setRegister(v0, res);
int64_t result = target(arg0, arg1, arg2, arg3);
if (external == intptr_t(&js::wasm::Instance::wait_i32))
result = int32_t(result);
setRegister(v0, result);
break;
}
case Args_Int_GeneralGeneralInt64Int64: {
Prototype_Int_GeneralGeneralInt64Int64 target =
reinterpret_cast<Prototype_Int_GeneralGeneralInt64Int64>(external);
int32_t res = target(arg0, arg1, arg2, arg3);
setRegister(v0, res);
int64_t result = target(arg0, arg1, arg2, arg3);
if (external == intptr_t(&js::wasm::Instance::wait_i64))
result = int32_t(result);
setRegister(v0, result);
break;
}
case Args_Int_DoubleIntInt: {
double dval = getFpuRegisterDouble(12);
Prototype_Int_DoubleIntInt target = reinterpret_cast<Prototype_Int_DoubleIntInt>(external);
int32_t res = target(dval, int32_t(arg1), int32_t(arg2));
setRegister(v0, res);
int64_t result = target(dval, arg1, arg2);
setRegister(v0, result);
break;
}
case Args_Int_IntDoubleIntInt: {
double dval = getFpuRegisterDouble(13);
Prototype_Int_IntDoubleIntInt target = reinterpret_cast<Prototype_Int_IntDoubleIntInt>(external);
int32_t res = target(int32_t(arg0), dval, int32_t(arg2), int32_t(arg3));
setRegister(v0, res);
int64_t result = target(arg0, dval, arg2, arg3);
setRegister(v0, result);
break;
}
case Args_Double_Double: {
@ -2297,20 +2306,20 @@ Simulator::softwareInterrupt(SimInstruction* instr)
}
case Args_Float32_IntInt: {
Prototype_Float32_IntInt target = reinterpret_cast<Prototype_Float32_IntInt>(external);
float fresult = target(int32_t(arg0), int32_t(arg1));
float fresult = target(arg0, arg1);
setCallResultFloat(fresult);
break;
}
case Args_Double_Int: {
Prototype_Double_Int target = reinterpret_cast<Prototype_Double_Int>(external);
double dresult = target(int32_t(arg0));
double dresult = target(arg0);
setCallResultDouble(dresult);
break;
}
case Args_Double_DoubleInt: {
double dval0 = getFpuRegisterDouble(12);
Prototype_Double_DoubleInt target = reinterpret_cast<Prototype_Double_DoubleInt>(external);
double dresult = target(dval0, int32_t(arg1));
double dresult = target(dval0, arg1);
setCallResultDouble(dresult);
break;
}
@ -2325,14 +2334,14 @@ Simulator::softwareInterrupt(SimInstruction* instr)
case Args_Double_IntDouble: {
double dval1 = getFpuRegisterDouble(13);
Prototype_Double_IntDouble target = reinterpret_cast<Prototype_Double_IntDouble>(external);
double dresult = target(int32_t(arg0), dval1);
double dresult = target(arg0, dval1);
setCallResultDouble(dresult);
break;
}
case Args_Int_IntDouble: {
double dval1 = getFpuRegisterDouble(13);
Prototype_Int_IntDouble target = reinterpret_cast<Prototype_Int_IntDouble>(external);
int32_t result = target(int32_t(arg0), dval1);
int64_t result = target(arg0, dval1);
setRegister(v0, result);
break;
}
@ -2730,7 +2739,7 @@ Simulator::configureTypeRegister(SimInstruction* instr,
alu_out = ~(rs | rt);
break;
case ff_slt:
alu_out = I32_CHECK(rs) < I32_CHECK(rt) ? 1 : 0;
alu_out = I64(rs) < I64(rt) ? 1 : 0;
break;
case ff_sltu:
alu_out = U64(rs) < U64(rt) ? 1 : 0;
@ -2774,7 +2783,7 @@ Simulator::configureTypeRegister(SimInstruction* instr,
}
break;
case ff_ddiv:
if (I32_CHECK(rs) == INT_MIN && I32_CHECK(rt) == -1) {
if (I64(rs) == INT64_MIN && I64(rt) == -1) {
i128hilo = U64(INT64_MIN);
} else {
uint64_t div = rs / rt;
@ -3086,65 +3095,72 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
result--;
}
setFpuRegisterLo(fd_reg, result);
if (setFCSRRoundError(fs_value, rounded)) {
if (setFCSRRoundError<int32_t>(fs_value, rounded))
setFpuRegisterLo(fd_reg, kFPUInvalidResult);
}
break;
}
case ff_trunc_w_fmt: { // Truncate float to word (round towards 0).
float rounded = truncf(fs_value);
int32_t result = I32(rounded);
setFpuRegisterLo(fd_reg, result);
if (setFCSRRoundError(fs_value, rounded)) {
if (setFCSRRoundError<int32_t>(fs_value, rounded))
setFpuRegisterLo(fd_reg, kFPUInvalidResult);
}
break;
}
case ff_floor_w_fmt: { // Round float to word towards negative infinity.
float rounded = std::floor(fs_value);
int32_t result = I32(rounded);
setFpuRegisterLo(fd_reg, result);
if (setFCSRRoundError(fs_value, rounded)) {
if (setFCSRRoundError<int32_t>(fs_value, rounded))
setFpuRegisterLo(fd_reg, kFPUInvalidResult);
}
break;
}
case ff_ceil_w_fmt: { // Round double to word towards positive infinity.
float rounded = std::ceil(fs_value);
int32_t result = I32(rounded);
setFpuRegisterLo(fd_reg, result);
if (setFCSRRoundError(fs_value, rounded)) {
if (setFCSRRoundError<int32_t>(fs_value, rounded))
setFpuRegisterLo(fd_reg, kFPUInvalidResult);
}
break;
}
case ff_cvt_l_fmt: { // Mips64r2: Truncate float to 64-bit long-word.
float rounded = truncf(fs_value);
i64 = I64(rounded);
setFpuRegister(fd_reg, i64);
break;
}
case ff_cvt_l_fmt: // Mips64r2: Truncate float to 64-bit long-word.
// Rounding modes are not yet supported.
MOZ_ASSERT((FCSR_ & 3) == 0);
// In rounding mode 0 it should behave like ROUND.
MOZ_FALLTHROUGH;
case ff_round_l_fmt: { // Mips64r2 instruction.
float rounded =
fs_value > 0 ? std::floor(fs_value + 0.5) : std::ceil(fs_value - 0.5);
i64 = I64(rounded);
setFpuRegister(fd_reg, i64);
if (setFCSRRoundError<int64_t>(fs_value, rounded))
setFpuRegister(fd_reg, kFPUInvalidResult64);
break;
}
case ff_trunc_l_fmt: { // Mips64r2 instruction.
float rounded = truncf(fs_value);
i64 = I64(rounded);
setFpuRegister(fd_reg, i64);
if (setFCSRRoundError<int64_t>(fs_value, rounded))
setFpuRegister(fd_reg, kFPUInvalidResult64);
break;
}
case ff_floor_l_fmt: // Mips64r2 instruction.
i64 = I64(std::floor(fs_value));
case ff_floor_l_fmt: { // Mips64r2 instruction.
float rounded = std::floor(fs_value);
i64 = I64(rounded);
setFpuRegister(fd_reg, i64);
if (setFCSRRoundError<int64_t>(fs_value, rounded))
setFpuRegister(fd_reg, kFPUInvalidResult64);
break;
case ff_ceil_l_fmt: // Mips64r2 instruction.
i64 = I64(std::ceil(fs_value));
}
case ff_ceil_l_fmt: { // Mips64r2 instruction.
float rounded = std::ceil(fs_value);
i64 = I64(rounded);
setFpuRegister(fd_reg, i64);
if (setFCSRRoundError<int64_t>(fs_value, rounded))
setFpuRegister(fd_reg, kFPUInvalidResult64);
break;
}
case ff_cvt_ps_s:
case ff_c_f_fmt:
MOZ_CRASH();
@ -3237,7 +3253,7 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
result--;
}
setFpuRegisterLo(fd_reg, result);
if (setFCSRRoundError(ds_value, rounded))
if (setFCSRRoundError<int32_t>(ds_value, rounded))
setFpuRegisterLo(fd_reg, kFPUInvalidResult);
break;
}
@ -3245,7 +3261,7 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
double rounded = trunc(ds_value);
int32_t result = I32(rounded);
setFpuRegisterLo(fd_reg, result);
if (setFCSRRoundError(ds_value, rounded))
if (setFCSRRoundError<int32_t>(ds_value, rounded))
setFpuRegisterLo(fd_reg, kFPUInvalidResult);
break;
}
@ -3253,7 +3269,7 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
double rounded = std::floor(ds_value);
int32_t result = I32(rounded);
setFpuRegisterLo(fd_reg, result);
if (setFCSRRoundError(ds_value, rounded))
if (setFCSRRoundError<int32_t>(ds_value, rounded))
setFpuRegisterLo(fd_reg, kFPUInvalidResult);
break;
}
@ -3261,40 +3277,51 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
double rounded = std::ceil(ds_value);
int32_t result = I32(rounded);
setFpuRegisterLo(fd_reg, result);
if (setFCSRRoundError(ds_value, rounded))
if (setFCSRRoundError<int32_t>(ds_value, rounded))
setFpuRegisterLo(fd_reg, kFPUInvalidResult);
break;
}
case ff_cvt_s_fmt: // Convert double to float (single).
setFpuRegisterFloat(fd_reg, static_cast<float>(ds_value));
break;
case ff_cvt_l_fmt: { // Mips64r2: Truncate double to 64-bit long-word.
double rounded = trunc(ds_value);
case ff_cvt_l_fmt: // Mips64r2: Truncate double to 64-bit long-word.
// Rounding modes are not yet supported.
MOZ_ASSERT((FCSR_ & 3) == 0);
// In rounding mode 0 it should behave like ROUND.
MOZ_FALLTHROUGH;
case ff_round_l_fmt: { // Mips64r2 instruction.
double rounded =
ds_value > 0 ? std::floor(ds_value + 0.5) : std::ceil(ds_value - 0.5);
i64 = I64(rounded);
setFpuRegister(fd_reg, i64);
if (setFCSRRoundError<int64_t>(ds_value, rounded))
setFpuRegister(fd_reg, kFPUInvalidResult64);
break;
}
case ff_trunc_l_fmt: { // Mips64r2 instruction.
double rounded = trunc(ds_value);
i64 = I64(rounded);
setFpuRegister(fd_reg, i64);
if (setFCSRRoundError<int64_t>(ds_value, rounded))
setFpuRegister(fd_reg, kFPUInvalidResult64);
break;
}
case ff_round_l_fmt: { // Mips64r2 instruction.
double rounded =
ds_value > 0 ? std::floor(ds_value + 0.5) : std::ceil(ds_value - 0.5);
case ff_floor_l_fmt: { // Mips64r2 instruction.
double rounded = std::floor(ds_value);
i64 = I64(rounded);
setFpuRegister(fd_reg, i64);
if (setFCSRRoundError<int64_t>(ds_value, rounded))
setFpuRegister(fd_reg, kFPUInvalidResult64);
break;
}
case ff_floor_l_fmt: // Mips64r2 instruction.
i64 = I64(std::floor(ds_value));
setFpuRegister(fd_reg, i64);
break;
case ff_ceil_l_fmt: // Mips64r2 instruction.
i64 = I64(std::ceil(ds_value));
case ff_ceil_l_fmt: { // Mips64r2 instruction.
double rounded = std::ceil(ds_value);
i64 = I64(rounded);
setFpuRegister(fd_reg, i64);
if (setFCSRRoundError<int64_t>(ds_value, rounded))
setFpuRegister(fd_reg, kFPUInvalidResult64);
break;
}
case ff_c_f_fmt:
MOZ_CRASH();
break;

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

@ -75,6 +75,7 @@ const int kNumFPURegisters = 32;
const int kFCSRRegister = 31;
const int kInvalidFPUControlRegister = -1;
const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1;
const uint64_t kFPUInvalidResult64 = static_cast<uint64_t>(1ULL << 63) - 1;
// FCSR constants.
const uint32_t kFCSRInexactFlagBit = 2;
@ -197,6 +198,7 @@ class Simulator {
double getFpuRegisterDouble(int fpureg) const;
void setFCSRBit(uint32_t cc, bool value);
bool testFCSRBit(uint32_t cc);
template <typename T>
bool setFCSRRoundError(double original, double rounded);
// Special case of set_register and get_register to access the raw PC value.

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

@ -0,0 +1,36 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
const languageTags = {
// The preferred value of "hy-arevela" is "hy".
"hy-arevela": "hy",
"hy-Armn-arevela": "hy-Armn",
"hy-AM-arevela": "hy-AM",
"hy-arevela-fonipa": "hy-fonipa",
"hy-fonipa-arevela": "hy-fonipa",
// The preferred value of "hy-arevmda" is "hyw".
"hy-arevmda": "hyw",
"hy-Armn-arevmda": "hyw-Armn",
"hy-AM-arevmda": "hyw-AM",
"hy-arevmda-fonipa": "hyw-fonipa",
"hy-fonipa-arevmda": "hyw-fonipa",
// The preferred value of "ja-Latn-hepburn-heploc" is "ja-Latn-alalc97".
"ja-Latn-hepburn-heploc": "ja-Latn-alalc97",
"ja-Latn-JP-hepburn-heploc": "ja-Latn-JP-alalc97",
// Ensure we don't emit "alalc97" when it is already present.
"ja-Latn-alalc97-hepburn-heploc": "ja-Latn-alalc97",
"ja-Latn-hepburn-alalc97-heploc": "ja-Latn-alalc97",
"ja-Latn-hepburn-heploc-alalc97": "ja-Latn-alalc97",
// No replacement when "heploc" appears before "hepburn".
"ja-Latn-heploc-hepburn": "ja-Latn-heploc-hepburn",
};
for (let [tag, canonical] of Object.entries(languageTags)) {
assertEq(Intl.getCanonicalLocales(tag)[0], canonical);
}
if (typeof reportCompare === "function")
reportCompare(0, 0);

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

@ -1669,6 +1669,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void
if (!script) {
// No error was reported, but no script produced. Assume we hit out of
// memory.
MOZ_DIAGNOSTIC_ASSERT(false);
ReportOutOfMemory(cx);
return nullptr;
}
@ -1705,6 +1706,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void
if (scripts.length() != expectedLength) {
// No error was reported, but fewer scripts produced than expected.
// Assume we hit out of memory.
MOZ_DIAGNOSTIC_ASSERT(false);
ReportOutOfMemory(cx);
return false;
}

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

@ -2460,7 +2460,7 @@ pref("security.csp.experimentalEnabled", false);
pref("security.csp.enableStrictDynamic", true);
#if defined(DEBUG) && !defined(ANDROID)
pref("csp.content_privileged_about_uris_without_csp", "blank,cache,certerror,credits,home,logo,neterror,newtab,printpreview,srcdoc,studies");
pref("csp.content_privileged_about_uris_without_csp", "blank,cache,credits,home,logo,newtab,printpreview,srcdoc,studies");
#endif
#ifdef NIGHTLY_BUILD

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

@ -13,6 +13,7 @@ cd "$SRCDIR/js/src"
export PATH="$PATH:$TOOLTOOL_CHECKOUT/cargo/bin:$TOOLTOOL_CHECKOUT/rustc/bin"
export RUST_BACKTRACE=1
export AUTOMATION=1
cargo build --verbose --frozen --features debugmozjs
cargo build --verbose --frozen

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

@ -308,18 +308,6 @@ class CheckSpiderMonkeyCommand(MachCommandBase):
self.bindir, executable_name('jsapi-tests'))]
jsapi_tests_result = subprocess.call(jsapi_tests_cmd)
print('running check-style')
check_style_cmd = [python, os.path.join(
self.topsrcdir, 'config', 'check_spidermonkey_style.py')]
check_style_result = subprocess.call(
check_style_cmd, cwd=self.topsrcdir)
print('running check-masm')
check_masm_cmd = [python, os.path.join(
self.topsrcdir, 'config', 'check_macroassembler_style.py')]
check_masm_result = subprocess.call(
check_masm_cmd, cwd=self.topsrcdir)
print('running check-js-msg-encoding')
check_js_msg_cmd = [python, os.path.join(
self.topsrcdir, 'config', 'check_js_msg_encoding.py')]
@ -327,7 +315,7 @@ class CheckSpiderMonkeyCommand(MachCommandBase):
check_js_msg_cmd, cwd=self.topsrcdir)
all_passed = jittest_result and jstest_result and jsapi_tests_result and \
check_style_result and check_masm_result and check_js_msg_result
check_js_msg_result
return all_passed

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

@ -1,4 +1,7 @@
[hkdf.https.worker.html]
disabled:
if ccov and (os == "win"): https://bugzilla.mozilla.org/show_bug.cgi?id=1434754
[short derivedKey, normal salt, SHA-384, with normal info with 0 length]
expected: FAIL

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

@ -1,4 +0,0 @@
[DOMRectList.html]
[DOMRectList [NoInterfaceObject\]]
expected: FAIL

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

@ -10,12 +10,12 @@ setup(() => {
});
test(() => {
assert_false('DOMRectList' in window);
}, 'DOMRectList [NoInterfaceObject]');
assert_true('DOMRectList' in window);
}, 'DOMRectList is not [NoInterfaceObject]');
test(() => {
assert_true(domRectList instanceof Array);
}, 'DOMRectList [LegacyArrayClass]');
assert_false(domRectList instanceof Array);
}, 'DOMRectList is not [LegacyArrayClass]');
test(() => {
assert_equals(domRectList.length, 1);

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

@ -649,7 +649,6 @@ EnvironmentAddonBuilder.prototype = {
theme: await this._getActiveTheme(),
activePlugins: this._getActivePlugins(atStartup),
activeGMPlugins: await this._getActiveGMPlugins(atStartup),
activeExperiment: {},
persona: personaId,
};

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

@ -265,10 +265,6 @@ Structure:
},
...
},
activeExperiment: { // obsolete in firefox 61, section is empty if there's no active experiment
id: <string>, // id
branch: <string>, // branch name
},
persona: <string>, // id of the current persona
},
experiments: {
@ -419,3 +415,11 @@ Just like activePlugins, this will report dummy values until the blocklist is lo
experiments
-----------
For each experiment we collect the ``id`` and the ``branch`` the client is enrolled in. Both fields are truncated to 100 characters and a warning is printed when that happens.
Version History
===============
- Firefox 61:
- Removed empty ``addons.activeExperiment`` (`bug 1452935 <https://bugzilla.mozilla.org/show_bug.cgi?id=1452935>`_).

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

@ -669,7 +669,6 @@ var EnvironmentData = {
this.renderAddonsObject(addons.activeAddons, addonSection, "activeAddons");
this.renderActivePlugins(addons.activePlugins, addonSection, "activePlugins");
this.renderKeyValueObject(addons.theme, addonSection, "theme");
this.renderKeyValueObject(addons.activeExperiment, addonSection, "activeExperiment");
this.renderAddonsObject(addons.activeGMPlugins, addonSection, "activeGMPlugins");
this.renderPersona(addons, addonSection, "persona");