Bug 1678618: Imlement a mechanism to fire page-removed event. r=mak

Differential Revision: https://phabricator.services.mozilla.com/D101114
This commit is contained in:
Daisuke Akatsuka 2021-02-15 02:47:37 +00:00
Родитель b89f612a23
Коммит a0b93f756d
7 изменённых файлов: 155 добавлений и 0 удалений

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

@ -47,6 +47,9 @@ class PlacesEvent : public nsWrapperCache {
return nullptr;
}
virtual const PlacesRanking* AsPlacesRanking() const { return nullptr; }
virtual const PlacesVisitRemoved* AsPlacesVisitRemoved() const {
return nullptr;
}
protected:
virtual ~PlacesEvent() = default;

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

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_PlacesVisitRemoved_h
#define mozilla_dom_PlacesVisitRemoved_h
#include "mozilla/dom/PlacesEvent.h"
namespace mozilla {
namespace dom {
class PlacesVisitRemoved final : public PlacesEvent {
public:
explicit PlacesVisitRemoved() : PlacesEvent(PlacesEventType::Page_removed) {}
static already_AddRefed<PlacesVisitRemoved> Constructor(
const GlobalObject& aGlobal, const PlacesVisitRemovedInit& aInitDict) {
MOZ_ASSERT(
aInitDict.mReason == PlacesVisitRemoved_Binding::REASON_DELETED ||
aInitDict.mReason == PlacesVisitRemoved_Binding::REASON_EXPIRED,
"The reason should be REASON_DELETED or REASON_EXPIRED");
MOZ_ASSERT(
!(aInitDict.mIsRemovedFromStore && aInitDict.mIsPartialVisistsRemoval),
"isRemovedFromStore and isPartialVisistsRemoval are inconsistent");
RefPtr<PlacesVisitRemoved> event = new PlacesVisitRemoved();
event->mUrl = aInitDict.mUrl;
event->mPageGuid = aInitDict.mPageGuid;
event->mReason = aInitDict.mReason;
event->mTransitionType = aInitDict.mTransitionType;
event->mIsRemovedFromStore = aInitDict.mIsRemovedFromStore;
event->mIsPartialVisistsRemoval = aInitDict.mIsPartialVisistsRemoval;
return event.forget();
}
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override {
return PlacesVisitRemoved_Binding::Wrap(aCx, this, aGivenProto);
}
const PlacesVisitRemoved* AsPlacesVisitRemoved() const override {
return this;
}
void GetUrl(nsString& aUrl) const { aUrl = mUrl; }
void GetPageGuid(nsCString& aPageGuid) const { aPageGuid = mPageGuid; }
uint16_t Reason() const { return mReason; }
uint32_t TransitionType() const { return mTransitionType; }
bool IsRemovedFromStore() const { return mIsRemovedFromStore; }
bool IsPartialVisistsRemoval() const { return mIsPartialVisistsRemoval; }
nsString mUrl;
nsCString mPageGuid;
uint16_t mReason;
uint32_t mTransitionType;
bool mIsRemovedFromStore;
bool mIsPartialVisistsRemoval;
private:
~PlacesVisitRemoved() = default;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PlacesVisitRemoved_h

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

@ -225,6 +225,7 @@ EXPORTS.mozilla.dom += [
"PlacesObservers.h",
"PlacesRanking.h",
"PlacesVisit.h",
"PlacesVisitRemoved.h",
"PlacesVisitTitle.h",
"PlacesWeakCallbackWrapper.h",
"PopupBlocker.h",

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

@ -31,6 +31,14 @@ enum PlacesEventType {
* data: PlacesRanking. Fired whenever pages ranking is changed.
*/
"pages-rank-changed",
/**
* data: PlacesVisitRemoved. Fired whenever a page or its visits are removed.
* This may be invoked when a page is removed from the store because it has no more
* visits, nor bookmarks. It may also be invoked when all or some of the page visits are
* removed, but the page itself is not removed from the store, because it may be
* bookmarked.
*/
"page-removed",
};
[ChromeOnly, Exposed=Window]
@ -264,3 +272,60 @@ interface PlacesHistoryCleared : PlacesEvent {
interface PlacesRanking : PlacesEvent {
constructor();
};
dictionary PlacesVisitRemovedInit {
required DOMString url;
required ByteString pageGuid;
required unsigned short reason;
unsigned long transitionType = 0;
boolean isRemovedFromStore = false;
boolean isPartialVisistsRemoval = false;
};
[ChromeOnly, Exposed=Window]
interface PlacesVisitRemoved : PlacesEvent {
/**
* Removed by the user.
*/
const unsigned short REASON_DELETED = 0;
/**
* Removed by periodic expiration.
*/
const unsigned short REASON_EXPIRED = 1;
constructor(PlacesVisitRemovedInit initDict);
/**
* The URI of the page.
*/
readonly attribute DOMString url;
/**
* The unique id associated with the page.
*/
readonly attribute ByteString pageGuid;
/**
* The reason of removal.
*/
readonly attribute unsigned short reason;
/**
* One of nsINavHistoryService.TRANSITION_*
* NOTE: Please refer this attribute only when isRemovedFromStore is false.
* Otherwise this will be 0.
*/
readonly attribute unsigned long transitionType;
/**
* This will be true if the page is removed from store.
* If false, only visits were removed, but not the page.
*/
readonly attribute boolean isRemovedFromStore;
/**
* This will be true if remains at least one visit to the page.
*/
readonly attribute boolean isPartialVisistsRemoval;
};

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

@ -1087,6 +1087,14 @@ var notifyCleanup = async function(db, pages, transition = -1) {
} else {
// The page has been entirely removed.
notify(observers, "onDeleteURI", [uri, guid, reason]);
PlacesObservers.notifyListeners([
new PlacesVisitRemoved({
url: uri.spec,
pageGuid: guid,
reason: PlacesVisitRemoved.REASON_DELETED,
isRemovedFromStore: true,
}),
]);
}
if (++notifiedCount % NOTIFICATION_CHUNK_SIZE == 0) {
// Every few notifications, yield time back to the main

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

@ -628,6 +628,14 @@ nsPlacesExpiration.prototype = {
// Dispatch expiration notifications to history.
if (wholeEntry) {
notify(observers, "onDeleteURI", [uri, guid, reason]);
PlacesObservers.notifyListeners([
new PlacesVisitRemoved({
url: uri.spec,
pageGuid: guid,
reason: PlacesVisitRemoved.REASON_EXPIRED,
isRemovedFromStore: true,
}),
]);
} else {
notify(observers, "onDeleteVisits", [
uri,

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

@ -433,6 +433,7 @@ module.exports = {
PlacesObservers: false,
PlacesRanking: false,
PlacesVisit: false,
PlacesVisitRemoved: false,
PlacesVisitTitle: false,
PlacesWeakCallbackWrapper: false,
Plugin: false,