Revision control

Copy as Markdown

Other Tools

ChromeUtils.defineModuleGetter(this, "PlacesUtils",
ChromeUtils.defineModuleGetter(this, "Promise",
// Need to explicitly load profile for Places
do_get_profile();
/**
* Waits until a new cache entry has been opened
*
* @return {Promise}
* @resolves When the new cache entry has been opened.
* @rejects Never.
*
*/
function promiseOpenCacheEntry(aKey, aAccessMode, aCacheSession)
{
let deferred = Promise.defer();
let cacheListener = {
onCacheEntryAvailable: function (entry, access, status) {
deferred.resolve(entry);
},
onCacheEntryDoomed: function (status) {
}
};
aCacheSession.asyncOpenCacheEntry(aKey, aAccessMode, cacheListener);
return deferred.promise;
}
/**
* 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.
*/
function promiseAsyncUpdates()
{
let deferred = Promise.defer();
let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
.DBConnection;
let begin = db.createAsyncStatement("BEGIN EXCLUSIVE");
begin.executeAsync();
begin.finalize();
let commit = db.createAsyncStatement("COMMIT");
commit.executeAsync({
handleResult: function() {},
handleError: function() {},
handleCompletion: function(aReason)
{
deferred.resolve();
}
});
commit.finalize();
return deferred.promise;
}
/**
* 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,
* transition: one of the TRANSITION_* from nsINavHistoryService,
* [optional] title: title of the page,
* [optional] visitDate: visit date in microseconds from the epoch
* [optional] referrer: nsIURI of the referrer for this visit
* }
*
* @return {Promise}
* @resolves When all visits have been added successfully.
* @rejects JavaScript exception.
*/
function promiseAddVisits(aPlaceInfo)
{
let deferred = Promise.defer();
let places = [];
if (aPlaceInfo instanceof Ci.nsIURI) {
places.push({ uri: aPlaceInfo });
}
else if (Array.isArray(aPlaceInfo)) {
places = places.concat(aPlaceInfo);
} else {
places.push(aPlaceInfo)
}
// Create mozIVisitInfo for each entry.
let now = Date.now();
for (let i = 0; i < places.length; i++) {
if (!places[i].title) {
places[i].title = "test visit for " + places[i].uri.spec;
}
places[i].visits = [{
transitionType: places[i].transition === undefined ? PlacesUtils.history.TRANSITION_LINK
: places[i].transition,
visitDate: places[i].visitDate || (now++) * 1000,
referrerURI: places[i].referrer
}];
}
PlacesUtils.asyncHistory.updatePlaces(
places,
{
handleError: function AAV_handleError(aResultCode, aPlaceInfo) {
let ex = new Components.Exception("Unexpected error in adding visits.",
aResultCode);
deferred.reject(ex);
},
handleResult: function () {},
handleCompletion: function UP_handleCompletion() {
deferred.resolve();
}
}
);
return deferred.promise;
}