Bug 1265836 - Part 4: Implement browser.history.addUrl. r=aswan

MozReview-Commit-ID: CBcKLvRLj3w

--HG--
extra : transplant_source : %BCXud%20%EC%BE%EA%161fN%B4%11%E2n%28b%95%8F
This commit is contained in:
Bob Silverberg 2016-05-19 21:55:37 -04:00
Родитель 77cec8a034
Коммит e580134ee3
3 изменённых файлов: 149 добавлений и 4 удалений

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

@ -14,6 +14,25 @@ const {
normalizeTime,
} = ExtensionUtils;
let historySvc = Ci.nsINavHistoryService;
const TRANSITION_TO_TRANSITION_TYPES_MAP = new Map([
["link", historySvc.TRANSITION_LINK],
["typed", historySvc.TRANSITION_TYPED],
["auto_bookmark", historySvc.TRANSITION_BOOKMARK],
["auto_subframe", historySvc.TRANSITION_EMBED],
["manual_subframe", historySvc.TRANSITION_FRAMED_LINK],
]);
function getTransitionType(transition) {
// cannot set a default value for the transition argument as the framework sets it to null
transition = transition || "link";
let transitionType = TRANSITION_TO_TRANSITION_TYPES_MAP.get(transition);
if (!transitionType) {
throw new Error(`|${transition}| is not a supported transition for history`);
}
return transitionType;
}
/*
* Converts a nsINavHistoryResultNode into a plain object
*
@ -48,6 +67,32 @@ function convertNavHistoryContainerResultNode(container) {
extensions.registerSchemaAPI("history", "history", (extension, context) => {
return {
history: {
addUrl: function(details) {
let transition, date;
try {
transition = getTransitionType(details.transition);
} catch (error) {
return Promise.reject({message: error.message});
}
if (details.visitTime) {
date = normalizeTime(details.visitTime);
}
let pageInfo = {
title: details.title,
url: details.url,
visits: [
{
transition,
date,
},
],
};
try {
return History.insert(pageInfo).then(() => undefined);
} catch (error) {
return Promise.reject({message: error.message});
}
},
deleteAll: function() {
return History.clear();
},

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

@ -187,9 +187,8 @@
},
{
"name": "addUrl",
"unsupported": true,
"type": "function",
"description": "Adds a URL to the history at the current time with a $(topic:transition-types)[transition type] of \"link\".",
"description": "Adds a URL to the history with a default visitTime of the current time and a default $(topic:transition-types)[transition type] of \"link\".",
"async": "callback",
"parameters": [
{
@ -198,7 +197,22 @@
"properties": {
"url": {
"type": "string",
"description": "The URL to add."
"description": "The URL to add. Must be a valid URL that can be added to history."
},
"title": {
"type": "string",
"optional": true,
"description": "The title of the page."
},
"transition": {
"$ref": "TransitionType",
"optional": true,
"description": "The $(topic:transition-types)[transition type] for this visit from its referrer."
},
"visitTime": {
"$ref": "HistoryTime",
"optional": true,
"description": "The date when this visit occurred."
}
}
},

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

@ -4,6 +4,10 @@
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
"resource://testing-common/PlacesTestUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionUtils",
"resource://gre/modules/ExtensionUtils.jsm");
add_task(function* test_delete() {
function background() {
@ -30,7 +34,6 @@ add_task(function* test_delete() {
}
const REFERENCE_DATE = new Date(1999, 9, 9, 9, 9);
let {PlacesUtils} = Cu.import("resource://gre/modules/PlacesUtils.jsm", {});
let extension = ExtensionTestUtils.loadExtension({
manifest: {
@ -191,3 +194,86 @@ add_task(function* test_search() {
yield extension.unload();
yield PlacesTestUtils.clearHistory();
});
add_task(function* test_add_url() {
function background() {
const TEST_DOMAIN = "http://example.com/";
browser.test.onMessage.addListener((msg, testData) => {
let [details, type] = testData;
details.url = details.url || `${TEST_DOMAIN}${type}`;
if (msg === "add-url") {
details.title = `Title for ${type}`;
browser.history.addUrl(details).then(() => {
return browser.history.search({text: details.url});
}).then(results => {
browser.test.assertEq(1, results.length, "1 result found when searching for added URL");
browser.test.sendMessage("url-added", {details, result: results[0]});
});
} else if (msg === "expect-failure") {
let expectedMsg = testData[2];
browser.history.addUrl(details).then(() => {
browser.test.fail(`Expected error thrown for ${type}`);
}, error => {
browser.test.assertTrue(
error.message.includes(expectedMsg),
`"Expected error thrown when trying to add a URL with ${type}`
);
browser.test.sendMessage("add-failed");
});
}
});
browser.test.sendMessage("ready");
}
let addTestData = [
[{}, "default"],
[{visitTime: new Date()}, "with_date"],
[{visitTime: Date.now()}, "with_ms_number"],
[{visitTime: Date.now().toString()}, "with_ms_string"],
[{visitTime: new Date().toISOString()}, "with_iso_string"],
[{transition: "typed"}, "valid_transition"],
];
let failTestData = [
[{transition: "generated"}, "an invalid transition", "|generated| is not a supported transition for history"],
[{visitTime: Date.now() + 1000000}, "a future date", "cannot be a future date"],
[{url: "about.config"}, "an invalid url", "about.config is not a valid URL"],
];
function* checkUrl(results) {
ok(yield PlacesTestUtils.isPageInDB(results.details.url), `${results.details.url} found in history database`);
ok(PlacesUtils.isValidGuid(results.result.id), "URL was added with a valid id");
is(results.result.title, results.details.title, "URL was added with the correct title");
if (results.details.visitTime) {
is(results.result.lastVisitTime,
Number(ExtensionUtils.normalizeTime(results.details.visitTime)),
"URL was added with the correct date");
}
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
permissions: ["history"],
},
background: `(${background})()`,
});
yield PlacesTestUtils.clearHistory();
yield extension.startup();
yield extension.awaitMessage("ready");
for (let data of addTestData) {
extension.sendMessage("add-url", data);
let results = yield extension.awaitMessage("url-added");
yield checkUrl(results);
}
for (let data of failTestData) {
extension.sendMessage("expect-failure", data);
yield extension.awaitMessage("add-failed");
}
yield extension.unload();
});