зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1723972 - Don't process-switch for object/embed loads if we're falling back due to an error page. r=nika
Differential Revision: https://phabricator.services.mozilla.com/D121734
This commit is contained in:
Родитель
0abff0009c
Коммит
80748548b0
|
@ -263,7 +263,7 @@ class AutoSetLoadingToFalse {
|
|||
/// Helper functions
|
||||
///
|
||||
|
||||
static bool IsSuccessfulRequest(nsIRequest* aRequest, nsresult* aStatus) {
|
||||
bool nsObjectLoadingContent::IsSuccessfulRequest(nsIRequest* aRequest, nsresult* aStatus) {
|
||||
nsresult rv = aRequest->GetStatus(aStatus);
|
||||
if (NS_FAILED(rv) || NS_FAILED(*aStatus)) {
|
||||
return false;
|
||||
|
|
|
@ -136,6 +136,8 @@ class nsObjectLoadingContent : public nsImageLoadingContent,
|
|||
// id. If in doubt, return true.
|
||||
static bool MayResolve(jsid aId);
|
||||
|
||||
static bool IsSuccessfulRequest(nsIRequest*, nsresult* aStatus);
|
||||
|
||||
// Helper for WebIDL enumeration
|
||||
void GetOwnPropertyNames(JSContext* aCx,
|
||||
JS::MutableHandleVector<jsid> /* unused */,
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "nsDocShellLoadState.h"
|
||||
#include "nsDocShellLoadTypes.h"
|
||||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
#include "nsExternalHelperAppService.h"
|
||||
#include "nsHttpChannel.h"
|
||||
#include "nsIBrowser.h"
|
||||
|
@ -1526,9 +1527,16 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
|
|||
// If we're doing an <object>/<embed> load, we may be doing a document load at
|
||||
// this point. We never need to do a process switch for a non-document
|
||||
// <object> or <embed> load.
|
||||
if (!mIsDocumentLoad && !mChannel->IsDocument()) {
|
||||
LOG(("Process Switch Abort: non-document load"));
|
||||
return false;
|
||||
if (!mIsDocumentLoad) {
|
||||
if (!mChannel->IsDocument()) {
|
||||
LOG(("Process Switch Abort: non-document load"));
|
||||
return false;
|
||||
}
|
||||
nsresult status;
|
||||
if (!nsObjectLoadingContent::IsSuccessfulRequest(mChannel, &status)) {
|
||||
LOG(("Process Switch Abort: error page"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the loading BrowsingContext. This may not be the context which will be
|
||||
|
|
|
@ -1,52 +1,68 @@
|
|||
n<!DOCTYPE html>
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test that <object> renders its own fallback.</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
// The host exists but the resource is unavailable.
|
||||
const cross_origin_url_a = "http://{{hosts[alt][www]}}:{{ports[http][0]}}/foo.html";
|
||||
// The destination does not even exist and the navigation fails.
|
||||
const cross_origin_url_b = "http://{{hosts[alt][nonexistent]}}:{{ports[http][0]}}/foo.html";
|
||||
|
||||
// Returns a promise which is resolved when |callback| returns true. The |callback| is invoked at
|
||||
// every animation frame.
|
||||
function for_each_animation_frame(callback) {
|
||||
return new Promise((resolve) => {
|
||||
function on_raf() {
|
||||
if (!callback())
|
||||
resolve();
|
||||
window.requestAnimationFrame(on_raf);
|
||||
}
|
||||
window.requestAnimationFrame(on_raf);
|
||||
});
|
||||
}
|
||||
const URIS = [
|
||||
// The host exists but the resource is unavailable.
|
||||
"http://{{hosts[alt][www]}}:{{ports[http][0]}}/foo.html",
|
||||
// The destination does not even exist and the navigation fails.
|
||||
"http://{{hosts[alt][nonexistent]}}:{{ports[http][0]}}/foo.html",
|
||||
];
|
||||
|
||||
// Create an <object> with some fallback content.
|
||||
function create_object_with_fallback(url) {
|
||||
function create_object_with_fallback(url, t) {
|
||||
var object = document.createElement("object");
|
||||
var fallback = document.createElement("button");
|
||||
fallback.textContent = "FALLBACK CONTENT";
|
||||
object.appendChild(fallback);
|
||||
object.data = url;
|
||||
object.type = "text/html";
|
||||
let promise = new Promise(resolve => {
|
||||
object.addEventListener("load", t.unreached_func("Should never reach the load event"), {once: true});
|
||||
object.addEventListener("error", () => resolve(object), {once: true});
|
||||
});
|
||||
document.body.appendChild(object);
|
||||
return object;
|
||||
t.add_cleanup(() => object.remove());
|
||||
return promise;
|
||||
}
|
||||
|
||||
function area(el) {
|
||||
let bounds = el.getBoundingClientRect();
|
||||
return el.width * el.height;
|
||||
return bounds.width * bounds.height;
|
||||
}
|
||||
|
||||
promise_test(async() => {
|
||||
var object = create_object_with_fallback(cross_origin_url_a);
|
||||
await for_each_animation_frame(() => area(object.firstChild) > 0);
|
||||
object.parentElement.removeChild(object);
|
||||
object = create_object_with_fallback(cross_origin_url_b);
|
||||
await for_each_animation_frame(() => area(object.firstChild) > 0);
|
||||
object.parentElement.removeChild(object);
|
||||
}, "Verify fallback content for failed cross-origin navigations is shown correctly.");
|
||||
for (let uri of URIS) {
|
||||
promise_test(async(t) => {
|
||||
let object = await create_object_with_fallback(uri, t);
|
||||
|
||||
// XXX In Chrome this is needed, fallback doesn't seem to be ready after
|
||||
// the error event, which seems weird/odd.
|
||||
await new Promise(resolve => requestAnimationFrame(resolve));
|
||||
|
||||
assert_true(area(object.firstChild) > 0, "Should be showing fallback");
|
||||
|
||||
// Per https://html.spec.whatwg.org/#the-object-element:
|
||||
//
|
||||
// The object element can represent an external resource, which,
|
||||
// depending on the type of the resource, will either be treated as
|
||||
// image, as a child browsing context, or as an external resource to
|
||||
// be processed by a plugin.
|
||||
//
|
||||
// [...]
|
||||
//
|
||||
// If the load failed (e.g. there was an HTTP 404 error, there was a
|
||||
// DNS error), fire an event named error at the element, then jump to
|
||||
// the step below labeled fallback.
|
||||
//
|
||||
// (And that happens before "Determine the resource type" which is what
|
||||
// sets the nested browsing context).
|
||||
//
|
||||
// So the expected window.length is 0.
|
||||
assert_equals(window.length, 0);
|
||||
}, `Verify fallback content for failed cross-origin navigations is shown correctly: ${uri}`);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
|
Загрузка…
Ссылка в новой задаче