diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 7745d9524fd7..dd4022037557 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3022,7 +3022,8 @@ var BrowserOnClick = {
case "Browser:CertExceptionError":
this.onCertError(msg.target, msg.data.elementId,
msg.data.isTopFrame, msg.data.location,
- msg.data.securityInfoAsString);
+ msg.data.securityInfoAsString,
+ msg.data.frameId);
break;
case "Browser:OpenCaptivePortalPage":
CaptivePortalWatcher.ensureCaptivePortalTab();
@@ -3067,7 +3068,7 @@ var BrowserOnClick = {
}
},
- onCertError(browser, elementId, isTopFrame, location, securityInfoAsString) {
+ onCertError(browser, elementId, isTopFrame, location, securityInfoAsString, frameId) {
let secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
let securityInfo;
@@ -3118,9 +3119,10 @@ var BrowserOnClick = {
securityInfo = getSecurityInfo(securityInfoAsString);
let errorInfo = getDetailedCertErrorInfo(location,
securityInfo);
- browser.messageManager.sendAsyncMessage( "CertErrorDetails", {
+ browser.messageManager.sendAsyncMessage("CertErrorDetails", {
code: securityInfo.errorCode,
- info: errorInfo
+ info: errorInfo,
+ frameId,
});
break;
diff --git a/browser/base/content/content.js b/browser/base/content/content.js
index 0553fbf2ca28..33d60b28ca44 100644
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -234,30 +234,35 @@ var AboutNetAndCertErrorListener = {
chromeGlobal.addEventListener("AboutNetErrorResetPreferences", this, false, true);
},
- get isAboutNetError() {
- return content.document.documentURI.startsWith("about:neterror");
+ isAboutNetError(doc) {
+ return doc.documentURI.startsWith("about:neterror");
},
- get isAboutCertError() {
- return content.document.documentURI.startsWith("about:certerror");
+ isAboutCertError(doc) {
+ return doc.documentURI.startsWith("about:certerror");
},
receiveMessage(msg) {
- if (!this.isAboutCertError) {
- return;
- }
+ if (msg.name == "CertErrorDetails") {
+ let frameDocShell = WebNavigationFrames.findDocShell(msg.data.frameId, docShell);
+ // We need nsIWebNavigation to access docShell.document.
+ frameDocShell && frameDocShell.QueryInterface(Ci.nsIWebNavigation);
+ if (!frameDocShell || !this.isAboutCertError(frameDocShell.document)) {
+ return;
+ }
- switch (msg.name) {
- case "CertErrorDetails":
- this.onCertErrorDetails(msg);
- break;
- case "Browser:CaptivePortalFreed":
- this.onCaptivePortalFreed(msg);
- break;
+ this.onCertErrorDetails(msg, frameDocShell);
+ } else if (msg.name == "Browser:CaptivePortalFreed") {
+ // TODO: This check is not correct for frames.
+ if (!this.isAboutCertError(content.document)) {
+ return;
+ }
+
+ this.onCaptivePortalFreed(msg);
}
},
- _getCertValidityRange() {
+ _getCertValidityRange(docShell) {
let {securityInfo} = docShell.failedChannel;
securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
let certs = securityInfo.failedCertChain.getEnumerator();
@@ -275,10 +280,12 @@ var AboutNetAndCertErrorListener = {
return {notBefore, notAfter};
},
- onCertErrorDetails(msg) {
- let div = content.document.getElementById("certificateErrorText");
+ onCertErrorDetails(msg, docShell) {
+ let doc = docShell.document;
+
+ let div = doc.getElementById("certificateErrorText");
div.textContent = msg.data.info;
- let learnMoreLink = content.document.getElementById("learnMoreLink");
+ let learnMoreLink = doc.getElementById("learnMoreLink");
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
switch (msg.data.code) {
@@ -301,7 +308,7 @@ var AboutNetAndCertErrorListener = {
let lastFetched = Services.prefs.getIntPref(PREF_BLOCKLIST_LAST_FETCHED, 0) * 1000;
let now = Date.now();
- let certRange = this._getCertValidityRange();
+ let certRange = this._getCertValidityRange(docShell);
let approximateDate = now - difference * 1000;
// If the difference is more than a day, we last fetched the date in the last 5 days,
@@ -315,17 +322,12 @@ var AboutNetAndCertErrorListener = {
// negative difference means local time is behind server time
approximateDate = formatter.format(new Date(approximateDate));
- content.document.getElementById("wrongSystemTime_URL")
- .textContent = content.document.location.hostname;
- content.document.getElementById("wrongSystemTime_systemDate")
- .textContent = systemDate;
- content.document.getElementById("wrongSystemTime_actualDate")
- .textContent = approximateDate;
+ doc.getElementById("wrongSystemTime_URL").textContent = doc.location.hostname;
+ doc.getElementById("wrongSystemTime_systemDate").textContent = systemDate;
+ doc.getElementById("wrongSystemTime_actualDate").textContent = approximateDate;
- content.document.getElementById("errorShortDesc")
- .style.display = "none";
- content.document.getElementById("wrongSystemTimePanel")
- .style.display = "block";
+ doc.getElementById("errorShortDesc").style.display = "none";
+ doc.getElementById("wrongSystemTimePanel").style.display = "block";
// If there is no clock skew with Kinto servers, check against the build date.
// (The Kinto ping could have happened when the time was still right, or not at all)
@@ -348,15 +350,13 @@ var AboutNetAndCertErrorListener = {
dateStyle: "short"
});
- content.document.getElementById("wrongSystemTimeWithoutReference_URL")
- .textContent = content.document.location.hostname;
- content.document.getElementById("wrongSystemTimeWithoutReference_systemDate")
+ doc.getElementById("wrongSystemTimeWithoutReference_URL")
+ .textContent = doc.location.hostname;
+ doc.getElementById("wrongSystemTimeWithoutReference_systemDate")
.textContent = formatter.format(systemDate);
- content.document.getElementById("errorShortDesc")
- .style.display = "none";
- content.document.getElementById("wrongSystemTimeWithoutReferencePanel")
- .style.display = "block";
+ doc.getElementById("errorShortDesc").style.display = "none";
+ doc.getElementById("wrongSystemTimeWithoutReferencePanel").style.display = "block";
}
}
learnMoreLink.href = baseURL + "time-errors";
@@ -369,13 +369,20 @@ var AboutNetAndCertErrorListener = {
},
handleEvent(aEvent) {
- if (!this.isAboutNetError && !this.isAboutCertError) {
+ let doc;
+ if (aEvent.originalTarget instanceof Ci.nsIDOMDocument) {
+ doc = aEvent.originalTarget;
+ } else {
+ doc = aEvent.originalTarget.ownerDocument;
+ }
+
+ if (!this.isAboutNetError(doc) && !this.isAboutCertError(doc)) {
return;
}
switch (aEvent.type) {
case "AboutNetErrorLoad":
- this.onPageLoad(aEvent);
+ this.onPageLoad(aEvent.originalTarget, doc.defaultView);
break;
case "AboutNetErrorOpenCaptivePortal":
this.openCaptivePortalPage(aEvent);
@@ -402,18 +409,16 @@ var AboutNetAndCertErrorListener = {
return false;
},
- onPageLoad(evt) {
+ onPageLoad(originalTarget, win) {
// Values for telemtery bins: see TLS_ERROR_REPORT_UI in Histograms.json
const TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN = 0;
- if (this.isAboutCertError) {
- let originalTarget = evt.originalTarget;
- let ownerDoc = originalTarget.ownerDocument;
- ClickEventHandler.onCertError(originalTarget, ownerDoc);
+ if (this.isAboutCertError(win.document)) {
+ ClickEventHandler.onCertError(originalTarget, win);
}
let automatic = Services.prefs.getBoolPref("security.ssl.errorReporting.automatic");
- content.dispatchEvent(new content.CustomEvent("AboutNetErrorOptions", {
+ win.dispatchEvent(new win.CustomEvent("AboutNetErrorOptions", {
detail: JSON.stringify({
enabled: Services.prefs.getBoolPref("security.ssl.errorReporting.enabled"),
changedCertPrefs: this.changedCertPrefs(),
@@ -442,9 +447,7 @@ var AboutNetAndCertErrorListener = {
// If we're enabling reports, send a report for this failure.
if (evt.detail) {
let win = evt.originalTarget.ownerGlobal;
- let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
+ let docShell = win.document.docShell;
let {securityInfo} = docShell.failedChannel;
securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
@@ -478,13 +481,13 @@ var ClickEventHandler = {
// Handle click events from about pages
if (event.button == 0) {
- if (ownerDoc.documentURI.startsWith("about:certerror")) {
- this.onCertError(originalTarget, ownerDoc);
+ if (AboutNetAndCertErrorListener.isAboutCertError(ownerDoc)) {
+ this.onCertError(originalTarget, ownerDoc.defaultView);
return;
} else if (ownerDoc.documentURI.startsWith("about:blocked")) {
this.onAboutBlocked(originalTarget, ownerDoc);
return;
- } else if (ownerDoc.documentURI.startsWith("about:neterror")) {
+ } else if (AboutNetAndCertErrorListener.isAboutNetError(ownerDoc)) {
this.onAboutNetError(event, ownerDoc.documentURI);
return;
}
@@ -538,9 +541,7 @@ var ClickEventHandler = {
// Only when the owner doc has |mixedContentChannel| and the same origin
// should we allow mixed content.
json.allowMixedContent = false;
- let docshell = ownerDoc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
+ let docshell = ownerDoc.docShell;
if (docShell.mixedContentChannel) {
const sm = Services.scriptSecurityManager;
try {
@@ -562,14 +563,13 @@ var ClickEventHandler = {
}
},
- onCertError(targetElement, ownerDoc) {
- let docShell = ownerDoc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
+ onCertError(targetElement, win) {
+ let docShell = win.document.docShell;
sendAsyncMessage("Browser:CertExceptionError", {
- location: ownerDoc.location.href,
+ frameId: WebNavigationFrames.getFrameId(win),
+ location: win.document.location.href,
elementId: targetElement.getAttribute("id"),
- isTopFrame: (ownerDoc.defaultView.parent === ownerDoc.defaultView),
+ isTopFrame: (win.parent === win),
securityInfoAsString: getSerializedSecurityInfo(docShell),
});
},
diff --git a/browser/base/content/test/about/browser.ini b/browser/base/content/test/about/browser.ini
index 1655d001b67c..25fb829e8dbe 100644
--- a/browser/base/content/test/about/browser.ini
+++ b/browser/base/content/test/about/browser.ini
@@ -9,6 +9,8 @@ support-files =
POSTSearchEngine.xml
[browser_aboutCertError.js]
+support-files =
+ dummy_page.html
[browser_aboutHome_imitate.js]
[browser_aboutHome_input.js]
skip-if = true # Bug 1409054 to remove; previously skipped for intermittents, e.g., Bug 1399648
diff --git a/browser/base/content/test/about/browser_aboutCertError.js b/browser/base/content/test/about/browser_aboutCertError.js
index 625f9d33da60..ee8a8a18e792 100644
--- a/browser/base/content/test/about/browser_aboutCertError.js
+++ b/browser/base/content/test/about/browser_aboutCertError.js
@@ -6,104 +6,150 @@
// This is testing the aboutCertError page (Bug 1207107).
const GOOD_PAGE = "https://example.com/";
+const GOOD_PAGE_2 = "https://example.org/";
+const DUMMY_PAGE = getRootDirectory(gTestPath).replace("chrome://mochitests/content", GOOD_PAGE) + "dummy_page.html";
const BAD_CERT = "https://expired.example.com/";
const UNKNOWN_ISSUER = "https://self-signed.example.com ";
const BAD_STS_CERT = "https://badchain.include-subdomains.pinning.example.com:443";
const {TabStateFlusher} = ChromeUtils.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
+function injectErrorPageFrame(tab, src) {
+ return ContentTask.spawn(tab.linkedBrowser, {frameSrc: src}, async function({frameSrc}) {
+ let loaded = ContentTaskUtils.waitForEvent(content.wrappedJSObject, "DOMFrameContentLoaded");
+ let iframe = content.document.createElement("iframe");
+ iframe.src = frameSrc;
+ content.document.body.appendChild(iframe);
+ await loaded;
+ // We will have race conditions when accessing the frame content after setting a src,
+ // so we can't wait for AboutNetErrorLoad. Let's wait for the certerror class to
+ // appear instead (which should happen at the same time as AboutNetErrorLoad).
+ await ContentTaskUtils.waitForCondition(() =>
+ iframe.contentDocument.body.classList.contains("certerror"));
+ });
+}
+
+async function openErrorPage(src, useFrame) {
+ let tab;
+ if (useFrame) {
+ info("Loading cert error page in an iframe");
+ tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, DUMMY_PAGE);
+ await injectErrorPageFrame(tab, src);
+ } else {
+ let certErrorLoaded;
+ tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
+ gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, src);
+ let browser = gBrowser.selectedBrowser;
+ certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
+ }, false);
+ info("Loading and waiting for the cert error");
+ await certErrorLoaded;
+ }
+
+ return tab;
+}
+
add_task(async function checkReturnToAboutHome() {
info("Loading a bad cert page directly and making sure 'return to previous page' goes to about:home");
- let browser;
- let certErrorLoaded;
- let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, BAD_CERT);
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
- }, false);
+ for (let useFrame of [false, true]) {
+ let tab = await openErrorPage(BAD_CERT, useFrame);
+ let browser = tab.linkedBrowser;
- info("Loading and waiting for the cert error");
- await certErrorLoaded;
+ is(browser.webNavigation.canGoBack, false, "!webNavigation.canGoBack");
+ is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
- is(browser.webNavigation.canGoBack, false, "!webNavigation.canGoBack");
- is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
+ // Populate the shistory entries manually, since it happens asynchronously
+ // and the following tests will be too soon otherwise.
+ await TabStateFlusher.flush(browser);
+ let {entries} = JSON.parse(ss.getTabState(tab));
+ is(entries.length, 1, "there is one shistory entry");
- // Populate the shistory entries manually, since it happens asynchronously
- // and the following tests will be too soon otherwise.
- await TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "there is one shistory entry");
+ info("Clicking the go back button on about:certerror");
+ await ContentTask.spawn(browser, {frame: useFrame}, async function({frame}) {
+ let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
- info("Clicking the go back button on about:certerror");
- await ContentTask.spawn(browser, null, async function() {
- let doc = content.document;
- let returnButton = doc.getElementById("returnButton");
- is(returnButton.getAttribute("autofocus"), "true", "returnButton has autofocus");
- returnButton.click();
+ let returnButton = doc.getElementById("returnButton");
+ if (!frame) {
+ is(returnButton.getAttribute("autofocus"), "true", "returnButton has autofocus");
+ }
+ returnButton.click();
- await ContentTaskUtils.waitForEvent(this, "pageshow", true);
- });
+ await ContentTaskUtils.waitForEvent(this, "pageshow", true);
+ });
- is(browser.webNavigation.canGoBack, true, "webNavigation.canGoBack");
- is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
- is(gBrowser.currentURI.spec, "about:home", "Went back");
+ is(browser.webNavigation.canGoBack, true, "webNavigation.canGoBack");
+ is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
+ is(gBrowser.currentURI.spec, "about:home", "Went back");
- await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ }
});
add_task(async function checkReturnToPreviousPage() {
info("Loading a bad cert page and making sure 'return to previous page' goes back");
- let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE);
- let browser = gBrowser.selectedBrowser;
+ for (let useFrame of [false, true]) {
+ let tab;
+ let browser;
+ if (useFrame) {
+ tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE);
+ browser = tab.linkedBrowser;
- info("Loading and waiting for the cert error");
- let certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
- BrowserTestUtils.loadURI(browser, BAD_CERT);
- await certErrorLoaded;
+ BrowserTestUtils.loadURI(browser, GOOD_PAGE_2);
+ await BrowserTestUtils.browserLoaded(browser, false, GOOD_PAGE_2);
+ await injectErrorPageFrame(tab, BAD_CERT);
+ } else {
+ tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE);
+ browser = gBrowser.selectedBrowser;
- is(browser.webNavigation.canGoBack, true, "webNavigation.canGoBack");
- is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
+ info("Loading and waiting for the cert error");
+ let certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
+ BrowserTestUtils.loadURI(browser, BAD_CERT);
+ await certErrorLoaded;
+ }
- // Populate the shistory entries manually, since it happens asynchronously
- // and the following tests will be too soon otherwise.
- await TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 2, "there are two shistory entries");
+ is(browser.webNavigation.canGoBack, true, "webNavigation.canGoBack");
+ is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
- info("Clicking the go back button on about:certerror");
- await ContentTask.spawn(browser, null, async function() {
- let doc = content.document;
- let returnButton = doc.getElementById("returnButton");
- returnButton.click();
+ // Populate the shistory entries manually, since it happens asynchronously
+ // and the following tests will be too soon otherwise.
+ await TabStateFlusher.flush(browser);
+ let {entries} = JSON.parse(ss.getTabState(tab));
+ is(entries.length, 2, "there are two shistory entries");
- await ContentTaskUtils.waitForEvent(this, "pageshow", true);
- });
+ info("Clicking the go back button on about:certerror");
+ await ContentTask.spawn(browser, {frame: useFrame}, async function({frame}) {
+ let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
+ let returnButton = doc.getElementById("returnButton");
+ returnButton.click();
- is(browser.webNavigation.canGoBack, false, "!webNavigation.canGoBack");
- is(browser.webNavigation.canGoForward, true, "webNavigation.canGoForward");
- is(gBrowser.currentURI.spec, GOOD_PAGE, "Went back");
+ await ContentTaskUtils.waitForEvent(this, "pageshow", true);
+ });
- await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ is(browser.webNavigation.canGoBack, false, "!webNavigation.canGoBack");
+ is(browser.webNavigation.canGoForward, true, "webNavigation.canGoForward");
+ is(gBrowser.currentURI.spec, GOOD_PAGE, "Went back");
+
+ await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ }
});
add_task(async function checkBadStsCert() {
info("Loading a badStsCert and making sure exception button doesn't show up");
- await BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE);
- let browser = gBrowser.selectedBrowser;
- info("Loading and waiting for the cert error");
- let certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
- BrowserTestUtils.loadURI(browser, BAD_STS_CERT);
- await certErrorLoaded;
+ for (let useFrame of [false, true]) {
+ let tab = await openErrorPage(BAD_STS_CERT, useFrame);
+ let browser = tab.linkedBrowser;
- let exceptionButtonHidden = await ContentTask.spawn(browser, null, async function() {
- let doc = content.document;
- let exceptionButton = doc.getElementById("exceptionDialogButton");
- return exceptionButton.hidden;
- });
- ok(exceptionButtonHidden, "Exception button is hidden");
+ let exceptionButtonHidden = await ContentTask.spawn(browser, {frame: useFrame}, async function({frame}) {
+ let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
+ let exceptionButton = doc.getElementById("exceptionDialogButton");
+ return exceptionButton.hidden;
+ });
- await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ ok(exceptionButtonHidden, "Exception button is hidden");
+
+ await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ }
});
// This checks that the appinfo.appBuildID starts with a date string,
@@ -221,155 +267,142 @@ add_task(async function checkWrongSystemTimeWarning() {
add_task(async function checkAdvancedDetails() {
info("Loading a bad cert page and verifying the main error and advanced details section");
- let browser;
- let certErrorLoaded;
- await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, BAD_CERT);
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
- }, false);
+ for (let useFrame of [false, true]) {
+ let tab = await openErrorPage(BAD_CERT, useFrame);
+ let browser = tab.linkedBrowser;
- info("Loading and waiting for the cert error");
- await certErrorLoaded;
+ let message = await ContentTask.spawn(browser, {frame: useFrame}, async function({frame}) {
+ let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
- let message = await ContentTask.spawn(browser, null, async function() {
- let doc = content.document;
- let shortDescText = doc.getElementById("errorShortDescText");
- info("Main error text: " + shortDescText.textContent);
- ok(shortDescText.textContent.includes("expired.example.com"),
- "Should list hostname in error message.");
+ let shortDescText = doc.getElementById("errorShortDescText");
+ info("Main error text: " + shortDescText.textContent);
+ ok(shortDescText.textContent.includes("expired.example.com"),
+ "Should list hostname in error message.");
- let advancedButton = doc.getElementById("advancedButton");
- advancedButton.click();
- let el = doc.getElementById("errorCode");
- return { textContent: el.textContent, tagName: el.tagName };
- });
- is(message.textContent, "SEC_ERROR_EXPIRED_CERTIFICATE",
- "Correct error message found");
- is(message.tagName, "a", "Error message is a link");
+ let advancedButton = doc.getElementById("advancedButton");
+ advancedButton.click();
+ let el = doc.getElementById("errorCode");
+ return { textContent: el.textContent, tagName: el.tagName };
+ });
+ is(message.textContent, "SEC_ERROR_EXPIRED_CERTIFICATE",
+ "Correct error message found");
+ is(message.tagName, "a", "Error message is a link");
- message = await ContentTask.spawn(browser, null, async function() {
- let doc = content.document;
- let errorCode = doc.getElementById("errorCode");
- errorCode.click();
- let div = doc.getElementById("certificateErrorDebugInformation");
- let text = doc.getElementById("certificateErrorText");
+ message = await ContentTask.spawn(browser, {frame: useFrame}, async function({frame}) {
+ let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
- let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
- .getService(Ci.nsISerializationHelper);
- let serializable = docShell.failedChannel.securityInfo
- .QueryInterface(Ci.nsITransportSecurityInfo)
- .QueryInterface(Ci.nsISerializable);
- let serializedSecurityInfo = serhelper.serializeToString(serializable);
- return {
- divDisplay: content.getComputedStyle(div).display,
- text: text.textContent,
- securityInfoAsString: serializedSecurityInfo
- };
- });
- isnot(message.divDisplay, "none", "Debug information is visible");
- ok(message.text.includes(BAD_CERT), "Correct URL found");
- ok(message.text.includes("Certificate has expired"),
- "Correct error message found");
- ok(message.text.includes("HTTP Strict Transport Security: false"),
- "Correct HSTS value found");
- ok(message.text.includes("HTTP Public Key Pinning: false"),
- "Correct HPKP value found");
- let certChain = getCertChain(message.securityInfoAsString);
- ok(message.text.includes(certChain), "Found certificate chain");
+ let errorCode = doc.getElementById("errorCode");
+ errorCode.click();
+ let div = doc.getElementById("certificateErrorDebugInformation");
+ let text = doc.getElementById("certificateErrorText");
- await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
+ .getService(Ci.nsISerializationHelper);
+ let serializable = doc.docShell.failedChannel.securityInfo
+ .QueryInterface(Ci.nsITransportSecurityInfo)
+ .QueryInterface(Ci.nsISerializable);
+ let serializedSecurityInfo = serhelper.serializeToString(serializable);
+ return {
+ divDisplay: content.getComputedStyle(div).display,
+ text: text.textContent,
+ securityInfoAsString: serializedSecurityInfo
+ };
+ });
+ isnot(message.divDisplay, "none", "Debug information is visible");
+ ok(message.text.includes(BAD_CERT), "Correct URL found");
+ ok(message.text.includes("Certificate has expired"),
+ "Correct error message found");
+ ok(message.text.includes("HTTP Strict Transport Security: false"),
+ "Correct HSTS value found");
+ ok(message.text.includes("HTTP Public Key Pinning: false"),
+ "Correct HPKP value found");
+ let certChain = getCertChain(message.securityInfoAsString);
+ ok(message.text.includes(certChain), "Found certificate chain");
+
+ await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ }
});
add_task(async function checkAdvancedDetailsForHSTS() {
info("Loading a bad STS cert page and verifying the advanced details section");
- let browser;
- let certErrorLoaded;
- await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, BAD_STS_CERT);
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
- }, false);
+ for (let useFrame of [false, true]) {
+ let tab = await openErrorPage(BAD_STS_CERT, useFrame);
+ let browser = tab.linkedBrowser;
- info("Loading and waiting for the cert error");
- await certErrorLoaded;
+ let message = await ContentTask.spawn(browser, {frame: useFrame}, async function({frame}) {
+ let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
- let message = await ContentTask.spawn(browser, null, async function() {
- let doc = content.document;
- let advancedButton = doc.getElementById("advancedButton");
- advancedButton.click();
- let ec = doc.getElementById("errorCode");
- let cdl = doc.getElementById("cert_domain_link");
- return {
- ecTextContent: ec.textContent,
- ecTagName: ec.tagName,
- cdlTextContent: cdl.textContent,
- cdlTagName: cdl.tagName
- };
- });
+ let advancedButton = doc.getElementById("advancedButton");
+ advancedButton.click();
+ let ec = doc.getElementById("errorCode");
+ let cdl = doc.getElementById("cert_domain_link");
+ return {
+ ecTextContent: ec.textContent,
+ ecTagName: ec.tagName,
+ cdlTextContent: cdl.textContent,
+ cdlTagName: cdl.tagName
+ };
+ });
- const badStsUri = Services.io.newURI(BAD_STS_CERT);
- is(message.ecTextContent, "SSL_ERROR_BAD_CERT_DOMAIN",
- "Correct error message found");
- is(message.ecTagName, "a", "Error message is a link");
- const url = badStsUri.prePath.slice(badStsUri.prePath.indexOf(".") + 1);
- is(message.cdlTextContent, url,
- "Correct cert_domain_link contents found");
- is(message.cdlTagName, "a", "cert_domain_link is a link");
+ const badStsUri = Services.io.newURI(BAD_STS_CERT);
+ is(message.ecTextContent, "SSL_ERROR_BAD_CERT_DOMAIN",
+ "Correct error message found");
+ is(message.ecTagName, "a", "Error message is a link");
+ const url = badStsUri.prePath.slice(badStsUri.prePath.indexOf(".") + 1);
+ is(message.cdlTextContent, url,
+ "Correct cert_domain_link contents found");
+ is(message.cdlTagName, "a", "cert_domain_link is a link");
- message = await ContentTask.spawn(browser, null, async function() {
- let doc = content.document;
- let errorCode = doc.getElementById("errorCode");
- errorCode.click();
- let div = doc.getElementById("certificateErrorDebugInformation");
- let text = doc.getElementById("certificateErrorText");
+ message = await ContentTask.spawn(browser, {frame: useFrame}, async function({frame}) {
+ let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
- let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
- .getService(Ci.nsISerializationHelper);
- let serializable = docShell.failedChannel.securityInfo
- .QueryInterface(Ci.nsITransportSecurityInfo)
- .QueryInterface(Ci.nsISerializable);
- let serializedSecurityInfo = serhelper.serializeToString(serializable);
- return {
- divDisplay: content.getComputedStyle(div).display,
- text: text.textContent,
- securityInfoAsString: serializedSecurityInfo
- };
- });
- isnot(message.divDisplay, "none", "Debug information is visible");
- ok(message.text.includes(badStsUri.spec), "Correct URL found");
- ok(message.text.includes("requested domain name does not match the server\u2019s certificate"),
- "Correct error message found");
- ok(message.text.includes("HTTP Strict Transport Security: false"),
- "Correct HSTS value found");
- ok(message.text.includes("HTTP Public Key Pinning: true"),
- "Correct HPKP value found");
- let certChain = getCertChain(message.securityInfoAsString);
- ok(message.text.includes(certChain), "Found certificate chain");
+ let errorCode = doc.getElementById("errorCode");
+ errorCode.click();
+ let div = doc.getElementById("certificateErrorDebugInformation");
+ let text = doc.getElementById("certificateErrorText");
- await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
+ .getService(Ci.nsISerializationHelper);
+ let serializable = doc.docShell.failedChannel.securityInfo
+ .QueryInterface(Ci.nsITransportSecurityInfo)
+ .QueryInterface(Ci.nsISerializable);
+ let serializedSecurityInfo = serhelper.serializeToString(serializable);
+ return {
+ divDisplay: content.getComputedStyle(div).display,
+ text: text.textContent,
+ securityInfoAsString: serializedSecurityInfo
+ };
+ });
+ isnot(message.divDisplay, "none", "Debug information is visible");
+ ok(message.text.includes(badStsUri.spec), "Correct URL found");
+ ok(message.text.includes("requested domain name does not match the server\u2019s certificate"),
+ "Correct error message found");
+ ok(message.text.includes("HTTP Strict Transport Security: false"),
+ "Correct HSTS value found");
+ ok(message.text.includes("HTTP Public Key Pinning: true"),
+ "Correct HPKP value found");
+ let certChain = getCertChain(message.securityInfoAsString);
+ ok(message.text.includes(certChain), "Found certificate chain");
+
+ await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ }
});
add_task(async function checkUnknownIssuerLearnMoreLink() {
info("Loading a cert error for self-signed pages and checking the correct link is shown");
- let browser;
- let certErrorLoaded;
- await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, UNKNOWN_ISSUER);
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
- }, false);
+ for (let useFrame of [false, true]) {
+ let tab = await openErrorPage(UNKNOWN_ISSUER, useFrame);
+ let browser = tab.linkedBrowser;
- info("Loading and waiting for the cert error");
- await certErrorLoaded;
+ let href = await ContentTask.spawn(browser, {frame: useFrame}, async function({frame}) {
+ let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
+ let learnMoreLink = doc.getElementById("learnMoreLink");
+ return learnMoreLink.href;
+ });
+ ok(href.endsWith("security-error"), "security-error in the Learn More URL");
- let href = await ContentTask.spawn(browser, null, async function() {
- let learnMoreLink = content.document.getElementById("learnMoreLink");
- return learnMoreLink.href;
- });
- ok(href.endsWith("security-error"), "security-error in the Learn More URL");
-
- await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ }
});
function getCertChain(securityInfoAsString) {
diff --git a/browser/base/content/test/about/dummy_page.html b/browser/base/content/test/about/dummy_page.html
new file mode 100644
index 000000000000..1a87e28408d0
--- /dev/null
+++ b/browser/base/content/test/about/dummy_page.html
@@ -0,0 +1,9 @@
+
+
+Dummy test page
+
+
+
+Dummy test page
+
+
diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js
index 7ad6e22aaf52..33f1c205c376 100644
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1212,6 +1212,10 @@ BrowserGlue.prototype = {
Services.tm.idleDispatchToMainThread(() => {
LanguagePrompt.init();
});
+
+ Services.tm.idleDispatchToMainThread(() => {
+ Services.blocklist.loadBlocklistAsync();
+ });
},
/**
diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm
index dee998cbe7eb..88de8a64f0fc 100644
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -3547,7 +3547,7 @@ var SessionStoreInternal = {
* a tab to speculatively connect on mouse hover.
*/
speculativeConnectOnTabHover(tab) {
- if (this._restore_on_demand && !tab.__SS_connectionPrepared && tab.hasAttribute("pending")) {
+ if (tab.__SS_lazyData && !tab.__SS_connectionPrepared) {
let url = this.getLazyTabValue(tab, "url");
let prepared = this.prepareConnectionToHost(url);
// This is used to test if a connection has been made beforehand.
diff --git a/devtools/client/netmonitor/src/components/RequestListContent.js b/devtools/client/netmonitor/src/components/RequestListContent.js
index 74858936c3b8..2b4dd0a1ad0a 100644
--- a/devtools/client/netmonitor/src/components/RequestListContent.js
+++ b/devtools/client/netmonitor/src/components/RequestListContent.js
@@ -15,7 +15,6 @@ const { formDataURI } = require("../utils/request-utils");
const {
getDisplayedRequests,
getSelectedRequest,
- getSortedRequests,
getWaterfallScale,
} = require("../selectors/index");
@@ -65,7 +64,6 @@ class RequestListContent extends Component {
openStatistics: PropTypes.func.isRequired,
scale: PropTypes.number,
selectedRequest: PropTypes.object,
- sortedRequests: PropTypes.array.isRequired,
requestFilterTypes: PropTypes.object.isRequired,
};
}
@@ -245,8 +243,8 @@ class RequestListContent extends Component {
onContextMenu(evt) {
evt.preventDefault();
- let { selectedRequest, sortedRequests } = this.props;
- this.contextMenu.open(evt, selectedRequest, sortedRequests);
+ let { selectedRequest, displayedRequests } = this.props;
+ this.contextMenu.open(evt, selectedRequest, displayedRequests);
}
/**
@@ -317,7 +315,6 @@ module.exports = connect(
firstRequestStartedMillis: state.requests.firstStartedMillis,
selectedRequest: getSelectedRequest(state),
scale: getWaterfallScale(state),
- sortedRequests: getSortedRequests(state),
requestFilterTypes: state.filters.requestFilterTypes,
}),
(dispatch, props) => ({
diff --git a/devtools/client/netmonitor/src/widgets/RequestListContextMenu.js b/devtools/client/netmonitor/src/widgets/RequestListContextMenu.js
index 85191c5f2b46..c6817db217fe 100644
--- a/devtools/client/netmonitor/src/widgets/RequestListContextMenu.js
+++ b/devtools/client/netmonitor/src/widgets/RequestListContextMenu.js
@@ -26,7 +26,7 @@ class RequestListContextMenu {
this.props = props;
}
- open(event, selectedRequest, sortedRequests) {
+ open(event, selectedRequest, requests) {
let {
id,
isCustom,
@@ -143,8 +143,8 @@ class RequestListContextMenu {
id: "request-list-context-copy-all-as-har",
label: L10N.getStr("netmonitor.context.copyAllAsHar"),
accesskey: L10N.getStr("netmonitor.context.copyAllAsHar.accesskey"),
- visible: sortedRequests.size > 0,
- click: () => this.copyAllAsHar(sortedRequests),
+ visible: requests.size > 0,
+ click: () => this.copyAllAsHar(requests),
});
menu.push({
@@ -158,8 +158,8 @@ class RequestListContextMenu {
id: "request-list-context-save-all-as-har",
label: L10N.getStr("netmonitor.context.saveAllAsHar"),
accesskey: L10N.getStr("netmonitor.context.saveAllAsHar.accesskey"),
- visible: sortedRequests.size > 0,
- click: () => this.saveAllAsHar(sortedRequests),
+ visible: requests.size > 0,
+ click: () => this.saveAllAsHar(requests),
});
menu.push({
@@ -219,7 +219,7 @@ class RequestListContextMenu {
id: "request-list-context-perf",
label: L10N.getStr("netmonitor.context.perfTools"),
accesskey: L10N.getStr("netmonitor.context.perfTools.accesskey"),
- visible: sortedRequests.size > 0,
+ visible: requests.size > 0,
click: () => openStatistics(true),
});
@@ -393,25 +393,25 @@ class RequestListContextMenu {
/**
* Copy HAR from the network panel content to the clipboard.
*/
- copyAllAsHar(sortedRequests) {
- return HarExporter.copy(this.getDefaultHarOptions(sortedRequests));
+ copyAllAsHar(requests) {
+ return HarExporter.copy(this.getDefaultHarOptions(requests));
}
/**
* Save HAR from the network panel content to a file.
*/
- saveAllAsHar(sortedRequests) {
+ saveAllAsHar(requests) {
// This will not work in launchpad
// document.execCommand(‘cut’/‘copy’) was denied because it was not called from
// inside a short running user-generated event handler.
// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Interact_with_the_clipboard
- return HarExporter.save(this.getDefaultHarOptions(sortedRequests));
+ return HarExporter.save(this.getDefaultHarOptions(requests));
}
- getDefaultHarOptions(sortedRequests) {
+ getDefaultHarOptions(requests) {
return {
connector: this.props.connector,
- items: sortedRequests,
+ items: requests,
};
}
}
diff --git a/devtools/server/actors/object.js b/devtools/server/actors/object.js
index 7bb4b2778356..a606f82bdbbe 100644
--- a/devtools/server/actors/object.js
+++ b/devtools/server/actors/object.js
@@ -1771,8 +1771,8 @@ DebuggerServer.ObjectActorPreviewers.Object = [
obj.class != "StyleSheetList" &&
obj.class != "CSSValueList" &&
obj.class != "NamedNodeMap" &&
- !(rawObj instanceof Ci.nsIDOMFileList ||
- rawObj instanceof Ci.nsIDOMNodeList)) {
+ obj.class != "FileList" &&
+ obj.class != "NodeList") {
return false;
}
diff --git a/docshell/base/nsDocShellTreeOwner.cpp b/docshell/base/nsDocShellTreeOwner.cpp
index 99233ef23992..2b4938925084 100644
--- a/docshell/base/nsDocShellTreeOwner.cpp
+++ b/docshell/base/nsDocShellTreeOwner.cpp
@@ -32,7 +32,6 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/SVGTitleElement.h"
#include "nsIDOMEvent.h"
-#include "nsIDOMFileList.h"
#include "nsIDOMMouseEvent.h"
#include "nsIFormControl.h"
#include "nsIImageLoadingContent.h"
diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp
index 8afba9ca73a8..85755de7468e 100644
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -145,7 +145,6 @@
#include "nsQueryObject.h"
#include "nsContentUtils.h"
#include "nsCSSProps.h"
-#include "nsIDOMFileList.h"
#include "nsIURIFixup.h"
#ifndef DEBUG
#include "nsIAppStartup.h"
diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp
index d53669b94626..36fadc9c9ff6 100644
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -144,7 +144,6 @@
#include "nsQueryObject.h"
#include "nsContentUtils.h"
#include "nsCSSProps.h"
-#include "nsIDOMFileList.h"
#include "nsIURIFixup.h"
#include "nsIURIMutator.h"
#ifndef DEBUG
diff --git a/dom/file/FileList.cpp b/dom/file/FileList.cpp
index 79aef3e065fb..87617fe158a4 100644
--- a/dom/file/FileList.cpp
+++ b/dom/file/FileList.cpp
@@ -16,8 +16,7 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FileList, mFiles, mParent)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FileList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileList)
- NS_INTERFACE_MAP_ENTRY(nsIDOMFileList)
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(FileList)
@@ -29,22 +28,6 @@ FileList::WrapObject(JSContext* aCx, JS::Handle aGivenProto)
return mozilla::dom::FileListBinding::Wrap(aCx, this, aGivenProto);
}
-NS_IMETHODIMP
-FileList::GetLength(uint32_t* aLength)
-{
- *aLength = Length();
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-FileList::Item(uint32_t aIndex, nsISupports** aValue)
-{
- nsCOMPtr file = Item(aIndex);
- file.forget(aValue);
- return NS_OK;
-}
-
File*
FileList::Item(uint32_t aIndex) const
{
diff --git a/dom/file/FileList.h b/dom/file/FileList.h
index 6539f878d7f3..0c39dd64e4cd 100644
--- a/dom/file/FileList.h
+++ b/dom/file/FileList.h
@@ -10,7 +10,6 @@
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/UnionTypes.h"
#include "nsCycleCollectionParticipant.h"
-#include "nsIDOMFileList.h"
#include "nsWrapperCache.h"
namespace mozilla {
@@ -19,15 +18,13 @@ namespace dom {
class BlobImpls;
class File;
-class FileList final : public nsIDOMFileList,
+class FileList final : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FileList)
- NS_DECL_NSIDOMFILELIST
-
explicit FileList(nsISupports* aParent)
: mParent(aParent)
{}
diff --git a/dom/file/moz.build b/dom/file/moz.build
index 2596b378de33..02c078d1fa37 100644
--- a/dom/file/moz.build
+++ b/dom/file/moz.build
@@ -11,7 +11,6 @@ DIRS += ['ipc']
XPIDL_SOURCES += [
'nsIDOMBlob.idl',
- 'nsIDOMFileList.idl',
]
XPIDL_MODULE = 'dom_file'
diff --git a/dom/file/nsIDOMFileList.idl b/dom/file/nsIDOMFileList.idl
deleted file mode 100644
index 8e6dcf52a3d8..000000000000
--- a/dom/file/nsIDOMFileList.idl
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "nsISupports.idl"
-
-[builtinclass, uuid(57128a85-34de-42db-a252-84dd57724a59)]
-interface nsIDOMFileList : nsISupports
-{
- readonly attribute unsigned long length;
- // returns a DOM File object
- nsISupports item(in unsigned long index);
-};
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index d62b5f1e8c27..042dfa822ffa 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -2755,12 +2755,11 @@ HTMLInputElement::SetFilesOrDirectories(const nsTArray& a
}
void
-HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
+HTMLInputElement::SetFiles(FileList* aFiles,
bool aSetValueChanged)
{
MOZ_ASSERT(mFileData);
- RefPtr files = static_cast(aFiles);
mFileData->mFilesOrDirectories.Clear();
mFileData->ClearGetFilesHelpers();
@@ -2770,12 +2769,11 @@ HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
}
if (aFiles) {
- uint32_t listLength;
- aFiles->GetLength(&listLength);
+ uint32_t listLength = aFiles->Length();
for (uint32_t i = 0; i < listLength; i++) {
OwningFileOrDirectory* element =
mFileData->mFilesOrDirectories.AppendElement();
- element->SetAsFile() = files->Item(i);
+ element->SetAsFile() = aFiles->Item(i);
}
}
diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h
index 753f4b920a87..1321bfd25df6 100644
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -274,7 +274,7 @@ public:
void SetFilesOrDirectories(const nsTArray& aFilesOrDirectories,
bool aSetValueChanged);
- void SetFiles(nsIDOMFileList* aFiles, bool aSetValueChanged);
+ void SetFiles(FileList* aFiles, bool aSetValueChanged);
// This method is used for test only. Onces the data is set, a 'change' event
// is dispatched.
diff --git a/dom/interfaces/html/nsIDOMHTMLInputElement.idl b/dom/interfaces/html/nsIDOMHTMLInputElement.idl
index b79806b7a210..fc6a1b3814f7 100644
--- a/dom/interfaces/html/nsIDOMHTMLInputElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLInputElement.idl
@@ -5,9 +5,6 @@
#include "nsISupports.idl"
-interface nsIControllers;
-interface nsIDOMFileList;
-
/**
* The nsIDOMHTMLInputElement interface is the interface to a [X]HTML
* input element.
diff --git a/dom/messagechannel/MessagePort.cpp b/dom/messagechannel/MessagePort.cpp
index 22f6abe06e57..e8cbf997c668 100644
--- a/dom/messagechannel/MessagePort.cpp
+++ b/dom/messagechannel/MessagePort.cpp
@@ -33,7 +33,6 @@
#include "nsIBFCacheEntry.h"
#include "nsIDocument.h"
-#include "nsIDOMFileList.h"
#include "nsIPresShell.h"
#include "nsISupportsPrimitives.h"
#include "nsServiceManagerUtils.h"
diff --git a/js/xpconnect/src/ExportHelpers.cpp b/js/xpconnect/src/ExportHelpers.cpp
index 4cda826c6834..8a22a7264bd6 100644
--- a/js/xpconnect/src/ExportHelpers.cpp
+++ b/js/xpconnect/src/ExportHelpers.cpp
@@ -17,7 +17,6 @@
#include "mozilla/dom/StructuredCloneHolder.h"
#include "nsGlobalWindow.h"
#include "nsJSUtils.h"
-#include "nsIDOMFileList.h"
using namespace mozilla;
using namespace mozilla::dom;
diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
index 7331bf51f20e..b3c82936f1da 100644
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -31,7 +31,6 @@
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/Scheduler.h"
#include "nsZipArchive.h"
-#include "nsIDOMFileList.h"
#include "nsWindowMemoryReporter.h"
#include "nsDOMClassInfo.h"
#include "ShimInterfaceInfo.h"
diff --git a/layout/forms/nsFileControlFrame.cpp b/layout/forms/nsFileControlFrame.cpp
index f15063b07549..837ada92d915 100644
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -25,7 +25,6 @@
#include "nsContentCreatorFunctions.h"
#include "nsContentUtils.h"
#include "mozilla/EventStates.h"
-#include "nsIDOMFileList.h"
#include "nsTextNode.h"
using namespace mozilla;
@@ -342,7 +341,7 @@ nsFileControlFrame::DnDListener::HandleEvent(nsIDOMEvent* aEvent)
}
nsresult
-nsFileControlFrame::DnDListener::GetBlobImplForWebkitDirectory(nsIDOMFileList* aFileList,
+nsFileControlFrame::DnDListener::GetBlobImplForWebkitDirectory(FileList* aFileList,
BlobImpl** aBlobImpl)
{
*aBlobImpl = nullptr;
@@ -360,12 +359,11 @@ nsFileControlFrame::DnDListener::GetBlobImplForWebkitDirectory(nsIDOMFileList* a
return NS_ERROR_FAILURE;
}
- FileList* files = static_cast(aFileList);
// webkitdirectory doesn't care about the length of the file list but
// only about the first item on it.
- uint32_t len = files->Length();
+ uint32_t len = aFileList->Length();
if (len) {
- File* file = files->Item(0);
+ File* file = aFileList->Item(0);
if (file) {
BlobImpl* impl = file->Impl();
if (impl && impl->IsDirectory()) {
@@ -406,7 +404,7 @@ nsFileControlFrame::DnDListener::CanDropTheseFiles(DataTransfer* aDataTransfer,
uint32_t listLength = 0;
if (fileList) {
- fileList->GetLength(&listLength);
+ listLength = fileList->Length();
}
return listLength <= 1 || aSupportsMultiple;
}
diff --git a/layout/forms/nsFileControlFrame.h b/layout/forms/nsFileControlFrame.h
index 243decd01d8e..b0bfb495d70b 100644
--- a/layout/forms/nsFileControlFrame.h
+++ b/layout/forms/nsFileControlFrame.h
@@ -14,9 +14,9 @@
#include "nsIAnonymousContentCreator.h"
#include "nsCOMPtr.h"
-class nsIDOMFileList;
namespace mozilla {
namespace dom {
+class FileList;
class BlobImpl;
class DataTransfer;
} // namespace dom
@@ -119,7 +119,7 @@ protected:
NS_DECL_NSIDOMEVENTLISTENER
- nsresult GetBlobImplForWebkitDirectory(nsIDOMFileList* aFileList,
+ nsresult GetBlobImplForWebkitDirectory(mozilla::dom::FileList* aFileList,
mozilla::dom::BlobImpl** aBlobImpl);
bool IsValidDropData(mozilla::dom::DataTransfer* aDataTransfer);
diff --git a/layout/tools/reftest/reftest-content.js b/layout/tools/reftest/reftest-content.js
index 28cce1d57b0c..e21383bf5b4a 100644
--- a/layout/tools/reftest/reftest-content.js
+++ b/layout/tools/reftest/reftest-content.js
@@ -582,7 +582,11 @@ function WaitForTestEnd(contentRootElement, inPrintMode, spellCheckedElements) {
return;
}
- FlushRendering();
+ // We don't need to flush styles any more when we are in the state
+ // after reftest-wait has removed.
+ if (state != STATE_WAITING_TO_FINISH) {
+ FlushRendering();
+ }
switch (state) {
case STATE_WAITING_TO_FIRE_INVALIDATE_EVENT: {
diff --git a/python/mozlint/mozlint/cli.py b/python/mozlint/mozlint/cli.py
index 1f0c3ab8d835..07c10adcf914 100644
--- a/python/mozlint/mozlint/cli.py
+++ b/python/mozlint/mozlint/cli.py
@@ -175,7 +175,7 @@ def run(paths, linters, fmt, outgoing, workdir, edit,
# Encode output with 'replace' to avoid UnicodeEncodeErrors on
# environments that aren't using utf-8.
- out = formatter(results, failed=lint.failed).encode(
+ out = formatter(results, failed=lint.failed | lint.failed_setup).encode(
sys.stdout.encoding or 'ascii', 'replace')
if out:
print(out)
diff --git a/python/mozlint/mozlint/roller.py b/python/mozlint/mozlint/roller.py
index 23a10383e012..402cae260743 100644
--- a/python/mozlint/mozlint/roller.py
+++ b/python/mozlint/mozlint/roller.py
@@ -12,6 +12,7 @@ from collections import defaultdict
from concurrent.futures import ProcessPoolExecutor
from math import ceil
from multiprocessing import cpu_count
+from multiprocessing.queues import Queue
from subprocess import CalledProcessError
from mozversioncontrol import get_repository_object, MissingUpstreamRepo, InvalidRepoPath
@@ -21,13 +22,27 @@ from .parser import Parser
from .pathutils import findobject
from .types import supported_types
+SHUTDOWN = False
+orig_sigint = signal.getsignal(signal.SIGINT)
-def _run_linters(config, paths, **lintargs):
+
+def _run_worker(config, paths, **lintargs):
results = defaultdict(list)
failed = []
+ if SHUTDOWN:
+ return results, failed
+
func = supported_types[config['type']]
- res = func(paths, config, **lintargs) or []
+ try:
+ res = func(paths, config, **lintargs) or []
+ except Exception:
+ traceback.print_exc()
+ res = 1
+ except (KeyboardInterrupt, SystemExit):
+ return results, failed
+ finally:
+ sys.stdout.flush()
if not isinstance(res, (list, tuple)):
if res:
@@ -38,16 +53,30 @@ def _run_linters(config, paths, **lintargs):
return results, failed
-def _run_worker(*args, **kwargs):
- try:
- return _run_linters(*args, **kwargs)
- except Exception:
- # multiprocessing seems to munge worker exceptions, print
- # it here so it isn't lost.
- traceback.print_exc()
- raise
- finally:
- sys.stdout.flush()
+class InterruptableQueue(Queue):
+ """A multiprocessing.Queue that catches KeyboardInterrupt when a worker is
+ blocking on it and returns None.
+
+ This is needed to gracefully handle KeyboardInterrupts when a worker is
+ blocking on ProcessPoolExecutor's call queue.
+ """
+
+ def get(self, *args, **kwargs):
+ try:
+ return Queue.get(self, *args, **kwargs)
+ except KeyboardInterrupt:
+ return None
+
+
+def _worker_sigint_handler(signum, frame):
+ """Sigint handler for the worker subprocesses.
+
+ Tells workers not to process the extra jobs on the call queue that couldn't
+ be canceled by the parent process.
+ """
+ global SHUTDOWN
+ SHUTDOWN = True
+ orig_sigint(signum, frame)
class LintRoller(object):
@@ -71,8 +100,11 @@ class LintRoller(object):
self.lintargs = lintargs
self.lintargs['root'] = root
- # linters that return non-zero
- self.failed = set()
+ # result state
+ self.failed = None
+ self.failed_setup = None
+ self.results = None
+
self.root = root
def read(self, paths):
@@ -91,7 +123,7 @@ class LintRoller(object):
if not self.linters:
raise LintersNotConfigured
- failed = set()
+ self.failed_setup = set()
for linter in self.linters:
if 'setup' not in linter:
continue
@@ -103,12 +135,12 @@ class LintRoller(object):
res = 1
if res:
- failed.add(linter['name'])
+ self.failed_setup.add(linter['name'])
- if failed:
- print("error: problem with lint setup, skipping {}".format(', '.join(sorted(failed))))
- self.linters = [l for l in self.linters if l['name'] not in failed]
- self.failed.update(failed)
+ if self.failed_setup:
+ print("error: problem with lint setup, skipping {}".format(
+ ', '.join(sorted(self.failed_setup))))
+ self.linters = [l for l in self.linters if l['name'] not in self.failed_setup]
return 1
return 0
@@ -120,6 +152,16 @@ class LintRoller(object):
yield linter, paths[:chunk_size]
paths = paths[chunk_size:]
+ def _collect_results(self, future):
+ if future.cancelled():
+ return
+
+ results, failed = future.result()
+ if failed:
+ self.failed.update(set(failed))
+ for k, v in results.iteritems():
+ self.results[k].extend(v)
+
def roll(self, paths=None, outgoing=None, workdir=None, num_procs=None):
"""Run all of the registered linters against the specified file paths.
@@ -133,6 +175,10 @@ class LintRoller(object):
if not self.linters:
raise LintersNotConfigured
+ # reset result state
+ self.results = defaultdict(list)
+ self.failed = set()
+
# Need to use a set in case vcs operations specify the same file
# more than once.
paths = paths or set()
@@ -170,19 +216,38 @@ class LintRoller(object):
paths = map(os.path.abspath, paths)
num_procs = num_procs or cpu_count()
- all_results = defaultdict(list)
- with ProcessPoolExecutor(num_procs) as executor:
- futures = [executor.submit(_run_worker, config, p, **self.lintargs)
- for config, p in self._generate_jobs(paths, num_procs)]
- # ignore SIGINT in parent so we can still get partial results
- # from child processes. These should shutdown quickly anyway.
- orig_sigint = signal.signal(signal.SIGINT, signal.SIG_IGN)
- for future in futures:
- results, failed = future.result()
- if failed:
- self.failed.update(set(failed))
- for k, v in results.iteritems():
- all_results[k].extend(v)
+ jobs = list(self._generate_jobs(paths, num_procs))
+ # Make sure we never spawn more processes than we have jobs.
+ num_procs = min(len(jobs), num_procs)
+
+ signal.signal(signal.SIGINT, _worker_sigint_handler)
+ executor = ProcessPoolExecutor(num_procs)
+ executor._call_queue = InterruptableQueue(executor._call_queue._maxsize)
+
+ # Submit jobs to the worker pool. The _collect_results method will be
+ # called when a job is finished. We store the futures so that they can
+ # be canceled in the event of a KeyboardInterrupt.
+ futures = []
+ for job in jobs:
+ future = executor.submit(_run_worker, *job, **self.lintargs)
+ future.add_done_callback(self._collect_results)
+ futures.append(future)
+
+ def _parent_sigint_handler(signum, frame):
+ """Sigint handler for the parent process.
+
+ Cancels all jobs that have not yet been placed on the call queue.
+ The parent process won't exit until all workers have terminated.
+ Assuming the linters are implemented properly, this shouldn't take
+ more than a couple seconds.
+ """
+ [f.cancel() for f in futures]
+ executor.shutdown(wait=False)
+ print("\nwarning: not all files were linted")
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+
+ signal.signal(signal.SIGINT, _parent_sigint_handler)
+ executor.shutdown()
signal.signal(signal.SIGINT, orig_sigint)
- return all_results
+ return self.results
diff --git a/python/mozlint/test/linters/external.py b/python/mozlint/test/linters/external.py
index 806a5fa1cfe8..3d3a68c387d4 100644
--- a/python/mozlint/test/linters/external.py
+++ b/python/mozlint/test/linters/external.py
@@ -5,6 +5,7 @@
from __future__ import absolute_import, print_function
import os
+import time
from mozlint import result
from mozlint.errors import LintException
@@ -36,6 +37,11 @@ def raises(files, config, **lintargs):
raise LintException("Oh no something bad happened!")
+def slow(files, config, **lintargs):
+ time.sleep(2)
+ return []
+
+
def structured(files, config, logger, **kwargs):
for path in files:
if os.path.isdir(path):
diff --git a/python/mozlint/test/linters/slow.yml b/python/mozlint/test/linters/slow.yml
new file mode 100644
index 000000000000..2c476790108c
--- /dev/null
+++ b/python/mozlint/test/linters/slow.yml
@@ -0,0 +1,8 @@
+---
+SlowLinter:
+ description: A linter that takes awhile to run
+ include:
+ - files
+ type: external
+ extensions: ['.js', '.jsm']
+ payload: external:slow
diff --git a/python/mozlint/test/runcli.py b/python/mozlint/test/runcli.py
new file mode 100644
index 000000000000..54be88b845d7
--- /dev/null
+++ b/python/mozlint/test/runcli.py
@@ -0,0 +1,20 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from __future__ import absolute_import
+
+import os
+import sys
+
+here = os.path.abspath(os.path.dirname(__file__))
+sys.path.insert(0, os.path.join(os.path.dirname(here), 'mozlint'))
+
+from mozlint import cli
+cli.SEARCH_PATHS.append(os.path.join(here, 'linters'))
+
+if __name__ == '__main__':
+ parser = cli.MozlintParser()
+ args = vars(parser.parse_args(sys.argv[1:]))
+ args['root'] = here
+ sys.exit(cli.run(**args))
diff --git a/python/mozlint/test/test_cli.py b/python/mozlint/test/test_cli.py
index 7e9f672a3e21..573e650a0af2 100644
--- a/python/mozlint/test/test_cli.py
+++ b/python/mozlint/test/test_cli.py
@@ -49,10 +49,11 @@ def test_cli_run_with_edit(run, parser, capfd):
out, err = capfd.readouterr()
out = out.splitlines()
assert ret == 1
- assert len(out) == 5
assert out[0].endswith('foobar.js') # from the `echo` editor
assert "foobar.js: line 1, col 1, Error" in out[1]
assert "foobar.js: line 2, col 1, Error" in out[2]
+ assert "2 problems" in out[-1]
+ assert len(out) == 5
del os.environ['EDITOR']
with pytest.raises(SystemExit):
diff --git a/python/mozlint/test/test_roller.py b/python/mozlint/test/test_roller.py
index a26598ab449f..7b9825dc156a 100644
--- a/python/mozlint/test/test_roller.py
+++ b/python/mozlint/test/test_roller.py
@@ -6,13 +6,16 @@ from __future__ import absolute_import
import os
import platform
+import signal
+import subprocess
import sys
+import time
import mozunit
import pytest
from mozlint import ResultContainer
-from mozlint.errors import LintersNotConfigured, LintException
+from mozlint.errors import LintersNotConfigured
here = os.path.abspath(os.path.dirname(__file__))
@@ -29,8 +32,10 @@ def test_roll_no_linters_configured(lint, files):
def test_roll_successful(lint, linters, files):
lint.read(linters)
+ assert lint.results is None
result = lint.roll(files)
assert len(result) == 1
+ assert lint.results == result
assert lint.failed == set([])
path = result.keys()[0]
@@ -45,15 +50,12 @@ def test_roll_successful(lint, linters, files):
assert container.rule == 'no-foobar'
-def test_roll_catch_exception(lint, lintdir, files):
+def test_roll_catch_exception(lint, lintdir, files, capfd):
lint.read(os.path.join(lintdir, 'raises.yml'))
- # suppress printed traceback from test output
- old_stderr = sys.stderr
- sys.stderr = open(os.devnull, 'w')
- with pytest.raises(LintException):
- lint.roll(files)
- sys.stderr = old_stderr
+ lint.roll(files) # assert not raises
+ out, err = capfd.readouterr()
+ assert 'LintException' in err
def test_roll_with_excluded_path(lint, linters, files):
@@ -76,13 +78,13 @@ def test_roll_with_invalid_extension(lint, lintdir, filedir):
def test_roll_with_failure_code(lint, lintdir, files):
lint.read(os.path.join(lintdir, 'badreturncode.yml'))
- assert lint.failed == set([])
+ assert lint.failed is None
result = lint.roll(files, num_procs=1)
assert len(result) == 0
assert lint.failed == set(['BadReturnCodeLinter'])
-def fake_run_linters(config, paths, **lintargs):
+def fake_run_worker(config, paths, **lintargs):
return {'count': [1]}, []
@@ -90,7 +92,7 @@ def fake_run_linters(config, paths, **lintargs):
reason="monkeypatch issues with multiprocessing on Windows")
@pytest.mark.parametrize('num_procs', [1, 4, 8, 16])
def test_number_of_jobs(monkeypatch, lint, linters, files, num_procs):
- monkeypatch.setattr(sys.modules[lint.__module__], '_run_linters', fake_run_linters)
+ monkeypatch.setattr(sys.modules[lint.__module__], '_run_worker', fake_run_worker)
lint.read(linters)
num_jobs = len(lint.roll(files, num_procs=num_procs)['count'])
@@ -105,7 +107,7 @@ def test_number_of_jobs(monkeypatch, lint, linters, files, num_procs):
reason="monkeypatch issues with multiprocessing on Windows")
@pytest.mark.parametrize('max_paths,expected_jobs', [(1, 12), (4, 6), (16, 6)])
def test_max_paths_per_job(monkeypatch, lint, linters, files, max_paths, expected_jobs):
- monkeypatch.setattr(sys.modules[lint.__module__], '_run_linters', fake_run_linters)
+ monkeypatch.setattr(sys.modules[lint.__module__], '_run_worker', fake_run_worker)
files = files[:4]
assert len(files) == 4
@@ -119,6 +121,23 @@ def test_max_paths_per_job(monkeypatch, lint, linters, files, max_paths, expecte
assert num_jobs == expected_jobs
+@pytest.mark.skipif(platform.system() == 'Windows',
+ reason="signal.CTRL_C_EVENT isn't causing a KeyboardInterrupt on Windows")
+def test_keyboard_interrupt():
+ # We use two linters so we'll have two jobs. One (string.yml) will complete
+ # quickly. The other (slow.yml) will run slowly. This way the first worker
+ # will be be stuck blocking on the ProcessPoolExecutor._call_queue when the
+ # signal arrives and the other still be doing work.
+ cmd = [sys.executable, 'runcli.py', '-l=string', '-l=slow']
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=here)
+ time.sleep(1)
+ proc.send_signal(signal.SIGINT)
+
+ out = proc.communicate()[0]
+ assert 'warning: not all files were linted' in out
+ assert 'Traceback' not in out
+
+
linters = ('setup.yml', 'setupfailed.yml', 'setupraised.yml')
@@ -133,7 +152,7 @@ def test_setup(lint, linters, filedir, capfd):
assert 'setup failed' in out
assert 'setup raised' in out
assert 'error: problem with lint setup, skipping' in out
- assert lint.failed == set(['SetupFailedLinter', 'SetupRaisedLinter'])
+ assert lint.failed_setup == set(['SetupFailedLinter', 'SetupRaisedLinter'])
if __name__ == '__main__':
diff --git a/servo/Cargo.lock b/servo/Cargo.lock
index ae1ca42f20e9..1270490786ff 100644
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -2815,6 +2815,7 @@ dependencies = [
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1",
"malloc_size_of_derive 0.0.1",
+ "style_traits 0.0.1",
"webrender_api 0.57.0 (git+https://github.com/servo/webrender)",
]
diff --git a/servo/components/compositing/compositor.rs b/servo/components/compositing/compositor.rs
index 88a3dc6b5eff..2b409b7ae3d4 100644
--- a/servo/components/compositing/compositor.rs
+++ b/servo/components/compositing/compositor.rs
@@ -21,7 +21,7 @@ use script_traits::{MouseButton, MouseEventType, ScrollState, TouchEventType, To
use script_traits::{UntrustedNodeAddress, WindowSizeData, WindowSizeType};
use script_traits::CompositorEvent::{MouseMoveEvent, MouseButtonEvent, TouchEvent};
use servo_config::opts;
-use servo_geometry::DeviceIndependentPixel;
+use servo_geometry::{DeviceIndependentPixel, DeviceUintLength};
use std::collections::HashMap;
use std::env;
use std::fs::File;
@@ -34,7 +34,7 @@ use style_traits::viewport::ViewportConstraints;
use time::{now, precise_time_ns, precise_time_s};
use touch::{TouchHandler, TouchAction};
use webrender;
-use webrender_api::{self, DeviceUintRect, DeviceUintSize, HitTestFlags, HitTestResult};
+use webrender_api::{self, DeviceIntPoint, DevicePoint, DeviceUintRect, DeviceUintSize, HitTestFlags, HitTestResult};
use webrender_api::{LayoutVector2D, ScrollEventPhase, ScrollLocation};
use windowing::{self, MouseWindowEvent, WebRenderDebugOption, WindowMethods};
@@ -202,7 +202,7 @@ struct ScrollZoomEvent {
/// Scroll by this offset, or to Start or End
scroll_location: ScrollLocation,
/// Apply changes to the frame at this location
- cursor: TypedPoint2D,
+ cursor: DeviceIntPoint,
/// The scroll event phase.
phase: ScrollEventPhase,
/// The number of OS events that have been coalesced together into this one event.
@@ -275,15 +275,15 @@ impl RenderTargetInfo {
}
}
-fn initialize_png(gl: &gl::Gl, width: usize, height: usize) -> RenderTargetInfo {
+fn initialize_png(gl: &gl::Gl, width: DeviceUintLength, height: DeviceUintLength) -> RenderTargetInfo {
let framebuffer_ids = gl.gen_framebuffers(1);
gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_ids[0]);
let texture_ids = gl.gen_textures(1);
gl.bind_texture(gl::TEXTURE_2D, texture_ids[0]);
- gl.tex_image_2d(gl::TEXTURE_2D, 0, gl::RGB as gl::GLint, width as gl::GLsizei,
- height as gl::GLsizei, 0, gl::RGB, gl::UNSIGNED_BYTE, None);
+ gl.tex_image_2d(gl::TEXTURE_2D, 0, gl::RGB as gl::GLint, width.get() as gl::GLsizei,
+ height.get() as gl::GLsizei, 0, gl::RGB, gl::UNSIGNED_BYTE, None);
gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as gl::GLint);
gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as gl::GLint);
@@ -297,8 +297,8 @@ fn initialize_png(gl: &gl::Gl, width: usize, height: usize) -> RenderTargetInfo
gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb);
gl.renderbuffer_storage(gl::RENDERBUFFER,
gl::DEPTH_COMPONENT24,
- width as gl::GLsizei,
- height as gl::GLsizei);
+ width.get() as gl::GLsizei,
+ height.get() as gl::GLsizei);
gl.framebuffer_renderbuffer(gl::FRAMEBUFFER,
gl::DEPTH_ATTACHMENT,
gl::RENDERBUFFER,
@@ -647,9 +647,11 @@ impl IOCompositor {
device_pixel_ratio: dppx,
initial_viewport: initial_viewport,
};
+
let top_level_browsing_context_id = self.root_pipeline.as_ref().map(|pipeline| {
pipeline.top_level_browsing_context_id
});
+
let msg = ConstellationMsg::WindowSize(top_level_browsing_context_id, data, size_type);
if let Err(e) = self.constellation_chan.send(msg) {
@@ -728,7 +730,7 @@ impl IOCompositor {
}
}
- fn hit_test_at_point(&self, point: TypedPoint2D) -> HitTestResult {
+ fn hit_test_at_point(&self, point: DevicePoint) -> HitTestResult {
let dppx = self.page_zoom * self.hidpi_factor();
let scaled_point = (point / dppx).to_untyped();
@@ -742,7 +744,7 @@ impl IOCompositor {
}
- pub fn on_mouse_window_move_event_class(&mut self, cursor: TypedPoint2D) {
+ pub fn on_mouse_window_move_event_class(&mut self, cursor: DevicePoint) {
if opts::get().convert_mouse_to_touch {
self.on_touch_move(TouchId(0), cursor);
return
@@ -751,7 +753,7 @@ impl IOCompositor {
self.dispatch_mouse_window_move_event_class(cursor);
}
- fn dispatch_mouse_window_move_event_class(&mut self, cursor: TypedPoint2D) {
+ fn dispatch_mouse_window_move_event_class(&mut self, cursor: DevicePoint) {
let root_pipeline_id = match self.get_root_pipeline_id() {
Some(root_pipeline_id) => root_pipeline_id,
None => return,
@@ -783,7 +785,7 @@ impl IOCompositor {
&self,
event_type: TouchEventType,
identifier: TouchId,
- point: TypedPoint2D)
+ point: DevicePoint)
{
let results = self.hit_test_at_point(point);
if let Some(item) = results.items.first() {
@@ -804,7 +806,7 @@ impl IOCompositor {
pub fn on_touch_event(&mut self,
event_type: TouchEventType,
identifier: TouchId,
- location: TypedPoint2D) {
+ location: DevicePoint) {
match event_type {
TouchEventType::Down => self.on_touch_down(identifier, location),
TouchEventType::Move => self.on_touch_move(identifier, location),
@@ -813,12 +815,12 @@ impl IOCompositor {
}
}
- fn on_touch_down(&mut self, identifier: TouchId, point: TypedPoint2D) {
+ fn on_touch_down(&mut self, identifier: TouchId, point: DevicePoint) {
self.touch_handler.on_touch_down(identifier, point);
self.send_touch_event(TouchEventType::Down, identifier, point);
}
- fn on_touch_move(&mut self, identifier: TouchId, point: TypedPoint2D) {
+ fn on_touch_move(&mut self, identifier: TouchId, point: DevicePoint) {
match self.touch_handler.on_touch_move(identifier, point) {
TouchAction::Scroll(delta) => {
match point.cast() {
@@ -849,7 +851,7 @@ impl IOCompositor {
}
}
- fn on_touch_up(&mut self, identifier: TouchId, point: TypedPoint2D) {
+ fn on_touch_up(&mut self, identifier: TouchId, point: DevicePoint) {
self.send_touch_event(TouchEventType::Up, identifier, point);
if let TouchAction::Click = self.touch_handler.on_touch_up(identifier, point) {
@@ -857,14 +859,14 @@ impl IOCompositor {
}
}
- fn on_touch_cancel(&mut self, identifier: TouchId, point: TypedPoint2D) {
+ fn on_touch_cancel(&mut self, identifier: TouchId, point: DevicePoint) {
// Send the event to script.
self.touch_handler.on_touch_cancel(identifier, point);
self.send_touch_event(TouchEventType::Cancel, identifier, point);
}
///
- fn simulate_mouse_click(&mut self, p: TypedPoint2D) {
+ fn simulate_mouse_click(&mut self, p: DevicePoint) {
let button = MouseButton::Left;
self.dispatch_mouse_window_move_event_class(p);
self.dispatch_mouse_window_event_class(MouseWindowEvent::MouseDown(button, p));
@@ -874,7 +876,7 @@ impl IOCompositor {
pub fn on_scroll_event(&mut self,
delta: ScrollLocation,
- cursor: TypedPoint2D,
+ cursor: DeviceIntPoint,
phase: TouchEventType) {
match phase {
TouchEventType::Move => self.on_scroll_window_event(delta, cursor),
@@ -889,7 +891,7 @@ impl IOCompositor {
fn on_scroll_window_event(&mut self,
scroll_location: ScrollLocation,
- cursor: TypedPoint2D) {
+ cursor: DeviceIntPoint) {
let event_phase = match (self.scroll_in_progress, self.in_scroll_transaction) {
(false, None) => ScrollEventPhase::Start,
(false, Some(last_scroll)) if last_scroll.elapsed() > Duration::from_millis(80) =>
@@ -908,7 +910,7 @@ impl IOCompositor {
fn on_scroll_start_window_event(&mut self,
scroll_location: ScrollLocation,
- cursor: TypedPoint2D) {
+ cursor: DeviceIntPoint) {
self.scroll_in_progress = true;
self.pending_scroll_zoom_events.push(ScrollZoomEvent {
magnification: 1.0,
@@ -921,7 +923,7 @@ impl IOCompositor {
fn on_scroll_end_window_event(&mut self,
scroll_location: ScrollLocation,
- cursor: TypedPoint2D) {
+ cursor: DeviceIntPoint) {
self.scroll_in_progress = false;
self.pending_scroll_zoom_events.push(ScrollZoomEvent {
magnification: 1.0,
@@ -1254,8 +1256,7 @@ impl IOCompositor {
fn composite_specific_target(&mut self,
target: CompositeTarget)
-> Result