Bug 1692655, r=nika,mtigley,smaug

Differential Revision: https://phabricator.services.mozilla.com/D141359
This commit is contained in:
Gijs Kruitbosch 2022-03-24 14:35:35 +00:00
Родитель f782dd8f45
Коммит ac8527d331
3 изменённых файлов: 56 добавлений и 76 удалений

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

@ -201,6 +201,13 @@ class AboutReaderParent extends JSWindowActorParent {
break;
}
case "RedirectTo": {
gCachedArticles.set(message.data.newURL, message.data.article);
// This is setup as a query so we can navigate the page after we've
// cached the relevant info in the parent.
return true;
}
default:
this.callListeners(message);
break;

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

@ -837,7 +837,12 @@ AboutReader.prototype = {
docContentType
);
} catch (e) {
if (e && e.newURL) {
if (e?.newURL && this._actor) {
await this._actor.sendQuery("RedirectTo", {
newURL: e.newURL,
article: e.article,
});
let readerURL = "about:reader?url=" + encodeURIComponent(e.newURL);
this._win.location.replace(readerURL);
return;

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

@ -135,7 +135,7 @@ var ReaderMode = {
});
let url = win.document.location.href;
let originalURL = ReaderMode.getOriginalUrl(url);
let originalURL = this.getOriginalUrl(url);
let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
if (!Services.appinfo.sessionHistoryInParent) {
@ -219,7 +219,7 @@ var ReaderMode = {
},
getOriginalUrlObjectForDisplay(url) {
let originalUrl = ReaderMode.getOriginalUrl(url);
let originalUrl = this.getOriginalUrl(url);
if (originalUrl) {
let uriObj;
try {
@ -264,10 +264,12 @@ var ReaderMode = {
* @resolves JS object representing the article, or null if no article is found.
*/
async downloadAndParseDocument(url, docContentType = "document") {
let doc = await this._downloadDocument(url, docContentType);
if (!doc) {
let result = await this._downloadDocument(url, docContentType);
if (!result?.doc) {
return null;
} else if (
}
let { doc, newURL } = result;
if (
!Readerable.shouldCheckUri(doc.documentURIObject) ||
!Readerable.shouldCheckUri(doc.baseURIObject, true)
) {
@ -275,7 +277,14 @@ var ReaderMode = {
return null;
}
return this._readerParse(doc);
let article = await this._readerParse(doc);
// If we have to redirect, reject to the caller with the parsed article,
// so we can update the URL before displaying it.
if (newURL) {
return Promise.reject({ newURL, article });
}
// Otherwise, we can just continue with the article.
return article;
},
_downloadDocument(url, docContentType = "document") {
@ -312,78 +321,37 @@ var ReaderMode = {
return;
}
if (xhr.responseType === "document") {
// Manually follow a meta refresh tag if one exists.
let meta = doc.querySelector("meta[http-equiv=refresh]");
if (meta) {
let content = meta.getAttribute("content");
if (content) {
let urlIndex = content.toUpperCase().indexOf("URL=");
if (urlIndex > -1) {
let baseURI = Services.io.newURI(url);
let newURI = Services.io.newURI(
content.substring(urlIndex + 4),
null,
baseURI
);
let newURL = newURI.spec;
let ssm = Services.scriptSecurityManager;
let flags =
ssm.LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT |
ssm.DISALLOW_INHERIT_PRINCIPAL;
try {
ssm.checkLoadURIStrWithPrincipal(
doc.nodePrincipal,
newURL,
flags
);
} catch (ex) {
let errorMsg =
"Reader mode disallowed meta refresh (reason: " + ex + ").";
if (Services.prefs.getBoolPref("reader.errors.includeURLs")) {
errorMsg += " Refresh target URI: '" + newURL + "'.";
}
reject(errorMsg);
return;
}
// Otherwise, pass an object indicating our new URL:
if (!baseURI.equalsExceptRef(newURI)) {
reject({ newURL });
return;
}
}
}
}
let responseURL = xhr.responseURL;
let givenURL = url;
// Convert these to real URIs to make sure the escaping (or lack
// thereof) is identical:
try {
responseURL = Services.io.newURI(responseURL).specIgnoringRef;
} catch (ex) {
/* Ignore errors - we'll use what we had before */
}
try {
givenURL = Services.io.newURI(givenURL).specIgnoringRef;
} catch (ex) {
/* Ignore errors - we'll use what we had before */
}
if (responseURL != givenURL) {
// We were redirected without a meta refresh tag.
// Force redirect to the correct place:
reject({ newURL: xhr.responseURL });
return;
}
} else {
let parser = new DOMParser();
let htmlString = `<pre>${doc}</pre>`;
doc = parser.parseFromString(htmlString, "text/html");
let responseURL = xhr.responseURL;
let givenURL = url;
// Convert these to real URIs to make sure the escaping (or lack
// thereof) is identical:
try {
responseURL = Services.io.newURI(responseURL).specIgnoringRef;
} catch (ex) {
/* Ignore errors - we'll use what we had before */
}
try {
givenURL = Services.io.newURI(givenURL).specIgnoringRef;
} catch (ex) {
/* Ignore errors - we'll use what we had before */
}
resolve(doc);
if (xhr.responseType != "document") {
let initialText = doc;
let parser = new DOMParser();
doc = parser.parseFromString(`<pre></pre>`, "text/html");
doc.querySelector("pre").textContent = initialText;
}
// We treat redirects as download successes here:
histogram.add(DOWNLOAD_SUCCESS);
let result = { doc };
if (responseURL != givenURL) {
result.newURL = xhr.responseURL;
}
resolve(result);
};
xhr.send();
});