Bug 1609163 - [remote] Implement Page.getNavigationHistory. r=remote-protocol-reviewers,maja_zf

Differential Revision: https://phabricator.services.mozilla.com/D60023

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Henrik Skupin 2020-01-20 18:59:20 +00:00
parent 9490b63809
commit 4645068db6
7 changed files with 166 additions and 2 deletions

View File

@ -91,6 +91,40 @@ class Page extends ContentProcessDomain {
}
}
/**
* Returns navigation history for the current page.
*
* @return {currentIndex:number, entries:Array<NavigationEntry>}
* Based on the transferMode setting data is a base64-encoded string,
* or stream is a handle to a OS.File stream.
*/
getNavigationHistory() {
const sessionHistory = this.docShell
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISHistory);
const entries = [];
for (let index = 0; index < sessionHistory.count; index++) {
const entry = sessionHistory.getEntryAtIndex(index);
const typedURL = entry.originalURI || entry.URI;
entries.push({
id: entry.ID,
url: entry.URI.spec,
userTypedURL: typedURL.spec,
title: entry.title,
// TODO: Bug 1609514
transitionType: null,
});
}
return {
currentIndex: sessionHistory.index,
entries,
};
}
async navigate({ url, referrer, transitionType, frameId } = {}) {
if (frameId && frameId != this.docShell.browsingContext.id.toString()) {
throw new UnsupportedError("frameId not supported");

View File

@ -265,9 +265,11 @@ function toDataURL(src, doctype = "html") {
/**
* Load a given URL in the currently selected tab
*/
async function loadURL(url) {
async function loadURL(url, expectedURL = undefined) {
expectedURL = expectedURL || url;
const browser = gBrowser.selectedTab.linkedBrowser;
const loaded = BrowserTestUtils.browserLoaded(browser, false, url);
const loaded = BrowserTestUtils.browserLoaded(browser, false, expectedURL);
BrowserTestUtils.loadURI(browser, url);
await loaded;

View File

@ -6,6 +6,8 @@ support-files =
!/remote/test/browser/chrome-remote-interface.js
!/remote/test/browser/head.js
head.js
doc_empty.html
sjs_redirect.sjs
[browser_bringToFront.js]
[browser_captureScreenshot.js]
@ -13,6 +15,7 @@ support-files =
[browser_frameNavigated.js]
[browser_frameNavigated_iframe.js]
[browser_getLayoutMetrics.js]
[browser_getNavigationHistory.js]
[browser_javascriptDialog_alert.js]
[browser_javascriptDialog_beforeunload.js]
[browser_javascriptDialog_confirm.js]

View File

@ -0,0 +1,65 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function singleEntry({ client }) {
const { Page } = client;
const data = generateHistoryData(1);
for (const entry of data) {
await loadURL(entry.userTypedURL);
}
const history = await Page.getNavigationHistory();
assertHistoryEntries(history, data, 0);
});
add_task(async function multipleEntriesWithLastIndex({ client }) {
const { Page } = client;
const data = generateHistoryData(3);
for (const entry of data) {
await loadURL(entry.userTypedURL);
}
const history = await Page.getNavigationHistory();
assertHistoryEntries(history, data, data.length - 1);
});
add_task(async function multipleEntriesWithFirstIndex({ client }) {
const { Page } = client;
const data = generateHistoryData(3);
for (const entry of data) {
await loadURL(entry.userTypedURL);
}
gBrowser.gotoIndex(0);
const history = await Page.getNavigationHistory();
assertHistoryEntries(history, data, 0);
});
add_task(async function locationRedirect({ client }) {
const { Page } = client;
const pageEmptyURL =
"http://example.com/browser/remote/test/browser/page/doc_empty.html";
const sjsURL =
"http://example.com/browser/remote/test/browser/page/sjs_redirect.sjs";
const redirectURL = `${sjsURL}?${pageEmptyURL}`;
const data = [
{
url: pageEmptyURL,
userTypedURL: redirectURL,
title: "Empty page",
},
];
await loadURL(redirectURL, pageEmptyURL);
const history = await Page.getNavigationHistory();
assertHistoryEntries(history, data, 0);
});

View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>Empty page</title>
</head>
<body>
</body>
</html>

View File

@ -10,6 +10,36 @@ Services.scriptloader.loadSubScript(
this
);
function assertHistoryEntries(history, expectedData, expectedIndex) {
const { currentIndex, entries } = history;
is(currentIndex, expectedIndex, "Got expected current index");
is(
entries.length,
expectedData.length,
"Found expected count of history entries"
);
entries.forEach((entry, index) => {
ok(!!entry.id, "History entry has an id set");
is(
entry.url,
expectedData[index].url,
"History entry has the correct URL set"
);
is(
entry.userTypedURL,
expectedData[index].userTypedURL,
"History entry has the correct user typed URL set"
);
is(
entry.title,
expectedData[index].title,
"History entry has the correct title set"
);
});
}
async function getContentSize() {
return SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
const docEl = content.document.documentElement;
@ -33,3 +63,18 @@ async function getViewportSize() {
};
});
}
function generateHistoryData(count) {
const data = [];
for (let index = 0; index < count; index++) {
const url = toDataURL(`<head><title>Test ${index + 1}</title></head>`);
data.push({
url,
userTypedURL: url,
title: `Test ${index + 1}`,
});
}
return data;
}

View File

@ -0,0 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, 301, "Moved Permanently");
response.setHeader("Location", request.queryString, false);
}