mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-22 12:23:08 +09:00
163 lines
5.5 KiB
JavaScript
163 lines
5.5 KiB
JavaScript
"use strict";
|
|
|
|
this.EXPORTED_SYMBOLS = [
|
|
"PlacesTestUtils",
|
|
];
|
|
|
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|
|
|
Cu.importGlobalProperties(["URL"]);
|
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
|
"resource://gre/modules/Task.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
|
"resource://gre/modules/PlacesUtils.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
|
"resource://gre/modules/NetUtil.jsm");
|
|
|
|
this.PlacesTestUtils = Object.freeze({
|
|
/**
|
|
* Asynchronously adds visits to a page.
|
|
*
|
|
* @param aPlaceInfo
|
|
* Can be an nsIURI, in such a case a single LINK visit will be added.
|
|
* Otherwise can be an object describing the visit to add, or an array
|
|
* of these objects:
|
|
* { uri: nsIURI of the page,
|
|
* [optional] transition: one of the TRANSITION_* from nsINavHistoryService,
|
|
* [optional] title: title of the page,
|
|
* [optional] visitDate: visit date, either in microseconds from the epoch or as a date object
|
|
* [optional] referrer: nsIURI of the referrer for this visit
|
|
* }
|
|
*
|
|
* @return {Promise}
|
|
* @resolves When all visits have been added successfully.
|
|
* @rejects JavaScript exception.
|
|
*/
|
|
addVisits: Task.async(function* (placeInfo) {
|
|
let places = [];
|
|
let infos = [];
|
|
|
|
if (placeInfo instanceof Ci.nsIURI ||
|
|
placeInfo instanceof URL ||
|
|
typeof placeInfo == "string") {
|
|
places.push({ uri: placeInfo });
|
|
}
|
|
else if (Array.isArray(placeInfo)) {
|
|
places = places.concat(placeInfo);
|
|
} else if (typeof placeInfo == "object" && placeInfo.uri) {
|
|
places.push(placeInfo)
|
|
} else {
|
|
throw new Error("Unsupported type passed to addVisits");
|
|
}
|
|
|
|
// Create a PageInfo for each entry.
|
|
for (let place of places) {
|
|
let info = {url: place.uri};
|
|
info.title = (typeof place.title === "string") ? place.title : "test visit for " + info.url.spec ;
|
|
if (typeof place.referrer == "string") {
|
|
place.referrer = NetUtil.newURI(place.referrer);
|
|
} else if (place.referrer && place.referrer instanceof URL) {
|
|
place.referrer = NetUtil.newURI(place.referrer.href);
|
|
}
|
|
let visitDate = place.visitDate;
|
|
if (visitDate) {
|
|
if (!(visitDate instanceof Date)) {
|
|
visitDate = PlacesUtils.toDate(visitDate);
|
|
}
|
|
} else {
|
|
visitDate = new Date();
|
|
}
|
|
info.visits = [{
|
|
transition: place.transition,
|
|
date: visitDate,
|
|
referrer: place.referrer
|
|
}];
|
|
infos.push(info);
|
|
}
|
|
return PlacesUtils.history.insertMany(infos);
|
|
}),
|
|
|
|
/**
|
|
* Clear all history.
|
|
*
|
|
* @return {Promise}
|
|
* @resolves When history was cleared successfully.
|
|
* @rejects JavaScript exception.
|
|
*/
|
|
clearHistory() {
|
|
let expirationFinished = new Promise(resolve => {
|
|
Services.obs.addObserver(function observe(subj, topic, data) {
|
|
Services.obs.removeObserver(observe, topic);
|
|
resolve();
|
|
}, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
|
|
});
|
|
|
|
return Promise.all([expirationFinished, PlacesUtils.history.clear()]);
|
|
},
|
|
|
|
/**
|
|
* Waits for all pending async statements on the default connection.
|
|
*
|
|
* @return {Promise}
|
|
* @resolves When all pending async statements finished.
|
|
* @rejects Never.
|
|
*
|
|
* @note The result is achieved by asynchronously executing a query requiring
|
|
* a write lock. Since all statements on the same connection are
|
|
* serialized, the end of this write operation means that all writes are
|
|
* complete. Note that WAL makes so that writers don't block readers, but
|
|
* this is a problem only across different connections.
|
|
*/
|
|
promiseAsyncUpdates() {
|
|
return PlacesUtils.withConnectionWrapper("promiseAsyncUpdates", Task.async(function* (db) {
|
|
try {
|
|
yield db.executeCached("BEGIN EXCLUSIVE");
|
|
yield db.executeCached("COMMIT");
|
|
} catch (ex) {
|
|
// If we fail to start a transaction, it's because there is already one.
|
|
// In such a case we should not try to commit the existing transaction.
|
|
}
|
|
}));
|
|
},
|
|
|
|
/**
|
|
* Asynchronously checks if an address is found in the database.
|
|
* @param aURI
|
|
* nsIURI or address to look for.
|
|
*
|
|
* @return {Promise}
|
|
* @resolves Returns true if the page is found.
|
|
* @rejects JavaScript exception.
|
|
*/
|
|
isPageInDB: Task.async(function* (aURI) {
|
|
let url = aURI instanceof Ci.nsIURI ? aURI.spec : aURI;
|
|
let db = yield PlacesUtils.promiseDBConnection();
|
|
let rows = yield db.executeCached(
|
|
"SELECT id FROM moz_places WHERE url_hash = hash(:url) AND url = :url",
|
|
{ url });
|
|
return rows.length > 0;
|
|
}),
|
|
|
|
/**
|
|
* Asynchronously checks how many visits exist for a specified page.
|
|
* @param aURI
|
|
* nsIURI or address to look for.
|
|
*
|
|
* @return {Promise}
|
|
* @resolves Returns the number of visits found.
|
|
* @rejects JavaScript exception.
|
|
*/
|
|
visitsInDB: Task.async(function* (aURI) {
|
|
let url = aURI instanceof Ci.nsIURI ? aURI.spec : aURI;
|
|
let db = yield PlacesUtils.promiseDBConnection();
|
|
let rows = yield db.executeCached(
|
|
`SELECT count(*) FROM moz_historyvisits v
|
|
JOIN moz_places h ON h.id = v.place_id
|
|
WHERE url_hash = hash(:url) AND url = :url`,
|
|
{ url });
|
|
return rows[0].getResultByIndex(0);
|
|
})
|
|
});
|