зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1678607: Apply bookmark-tags-changed event. r=mak
Depends on D128326 Differential Revision: https://phabricator.services.mozilla.com/D128327
This commit is contained in:
Родитель
4e72afc41d
Коммит
b3393c1f45
|
@ -343,7 +343,12 @@ var gEditItemOverlay = {
|
|||
PlacesUtils.bookmarks.addObserver(this);
|
||||
this.handlePlacesEvents = this.handlePlacesEvents.bind(this);
|
||||
PlacesUtils.observers.addListener(
|
||||
["bookmark-moved", "bookmark-title-changed", "bookmark-url-changed"],
|
||||
[
|
||||
"bookmark-moved",
|
||||
"bookmark-tags-changed",
|
||||
"bookmark-title-changed",
|
||||
"bookmark-url-changed",
|
||||
],
|
||||
this.handlePlacesEvents
|
||||
);
|
||||
window.addEventListener("unload", this);
|
||||
|
@ -561,7 +566,12 @@ var gEditItemOverlay = {
|
|||
if (this._observersAdded) {
|
||||
PlacesUtils.bookmarks.removeObserver(this);
|
||||
PlacesUtils.observers.removeListener(
|
||||
["bookmark-moved", "bookmark-title-changed", "bookmark-url-changed"],
|
||||
[
|
||||
"bookmark-moved",
|
||||
"bookmark-tags-changed",
|
||||
"bookmark-title-changed",
|
||||
"bookmark-url-changed",
|
||||
],
|
||||
this.handlePlacesEvents
|
||||
);
|
||||
window.removeEventListener("unload", this);
|
||||
|
@ -1154,6 +1164,11 @@ var gEditItemOverlay = {
|
|||
bm.title
|
||||
);
|
||||
break;
|
||||
case "bookmark-tags-changed":
|
||||
if (this._paneInfo.visibleRows.has("tagsRow")) {
|
||||
this._onTagsChange(event.guid).catch(Cu.reportError);
|
||||
}
|
||||
break;
|
||||
case "bookmark-title-changed":
|
||||
if (this._paneInfo.isItem || this._paneInfo.isTag) {
|
||||
// This also updates titles of folders in the folder menu list.
|
||||
|
@ -1291,11 +1306,6 @@ var gEditItemOverlay = {
|
|||
aParentId,
|
||||
aGuid
|
||||
) {
|
||||
if (aProperty == "tags" && this._paneInfo.visibleRows.has("tagsRow")) {
|
||||
this._onTagsChange(aGuid).catch(Cu.reportError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._paneInfo.isItem || this._paneInfo.itemId != aItemId) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -34,11 +34,15 @@ add_task(async function() {
|
|||
);
|
||||
|
||||
let promiseTagResetNotification = PlacesTestUtils.waitForNotification(
|
||||
"onItemChanged",
|
||||
(itemId, prop) => {
|
||||
let tags = PlacesUtils.tagging.getTagsForURI(uri);
|
||||
return prop == "tags" && tags.length == 1 && tags[0] == "tag1";
|
||||
}
|
||||
"bookmark-tags-changed",
|
||||
events =>
|
||||
events.some(event => {
|
||||
const tags = PlacesUtils.tagging.getTagsForURI(
|
||||
Services.io.newURI(event.url)
|
||||
);
|
||||
return tags.length === 1 && tags[0] === "tag1";
|
||||
}),
|
||||
"places"
|
||||
);
|
||||
|
||||
await withBookmarksDialog(
|
||||
|
@ -60,11 +64,15 @@ add_task(async function() {
|
|||
Assert.ok(!namepicker.readOnly, "Name field should not be read-only");
|
||||
Assert.equal(namepicker.value, "tag1", "Node title is correct");
|
||||
let promiseTagChangeNotification = PlacesTestUtils.waitForNotification(
|
||||
"onItemChanged",
|
||||
(itemId, prop) => {
|
||||
let tags = PlacesUtils.tagging.getTagsForURI(uri);
|
||||
return prop == "tags" && tags.length == 1 && tags[0] == "tag2";
|
||||
}
|
||||
"bookmark-tags-changed",
|
||||
events =>
|
||||
events.some(event => {
|
||||
const tags = PlacesUtils.tagging.getTagsForURI(
|
||||
Services.io.newURI(event.url)
|
||||
);
|
||||
return tags.length === 1 && tags[0] === "tag2";
|
||||
}),
|
||||
"places"
|
||||
);
|
||||
|
||||
let promiseTagRemoveNotification = PlacesTestUtils.waitForNotification(
|
||||
|
|
|
@ -103,8 +103,9 @@ add_task(async function test_add_bookmark_tags_from_bookmarkProperties() {
|
|||
// Click the bookmark star again, add more tags.
|
||||
await clickBookmarkStar();
|
||||
promiseNotification = PlacesTestUtils.waitForNotification(
|
||||
"onItemChanged",
|
||||
(id, property) => property == "tags"
|
||||
"bookmark-tags-changed",
|
||||
() => true,
|
||||
"places"
|
||||
);
|
||||
await fillBookmarkTextField(
|
||||
"editBMPanel_tagsField",
|
||||
|
|
|
@ -56,8 +56,9 @@ add_task(async function test_remove_tags_from_BookmarkStar() {
|
|||
);
|
||||
|
||||
let promiseTagsChange = PlacesTestUtils.waitForNotification(
|
||||
"onItemChanged",
|
||||
(id, property) => property === "tags"
|
||||
"bookmark-tags-changed",
|
||||
() => true,
|
||||
"places"
|
||||
);
|
||||
|
||||
// Update the "tags" field.
|
||||
|
@ -119,8 +120,9 @@ add_task(async function test_remove_tags_from_Toolbar() {
|
|||
);
|
||||
|
||||
let promiseTagsChange = PlacesTestUtils.waitForNotification(
|
||||
"onItemChanged",
|
||||
(id, property) => property === "tags"
|
||||
"bookmark-tags-changed",
|
||||
() => true,
|
||||
"places"
|
||||
);
|
||||
|
||||
// Update the "tags" field.
|
||||
|
@ -174,8 +176,9 @@ add_task(async function test_remove_tags_from_Sidebar() {
|
|||
);
|
||||
|
||||
let promiseTagsChange = PlacesTestUtils.waitForNotification(
|
||||
"onItemChanged",
|
||||
(id, property) => property === "tags"
|
||||
"bookmark-tags-changed",
|
||||
() => true,
|
||||
"places"
|
||||
);
|
||||
|
||||
// Update the "tags" field.
|
||||
|
|
|
@ -23,8 +23,9 @@ add_task(async function() {
|
|||
// add a tag
|
||||
document.getElementById("editBMPanel_tagsField").value = testTag;
|
||||
let promiseNotification = PlacesTestUtils.waitForNotification(
|
||||
"onItemChanged",
|
||||
(id, property) => property == "tags"
|
||||
"bookmark-tags-changed",
|
||||
() => true,
|
||||
"places"
|
||||
);
|
||||
gEditItemOverlay.onTagsFieldChange();
|
||||
await promiseNotification;
|
||||
|
|
|
@ -73,8 +73,9 @@ add_task(async function test_tags() {
|
|||
);
|
||||
|
||||
let promiseNotification = PlacesTestUtils.waitForNotification(
|
||||
"onItemChanged",
|
||||
(id, property) => property == "tags"
|
||||
"bookmark-tags-changed",
|
||||
() => true,
|
||||
"places"
|
||||
);
|
||||
|
||||
ContentTree.view.controller.doCommand("cmd_delete");
|
||||
|
|
|
@ -809,6 +809,7 @@ BookmarksTracker.prototype = {
|
|||
"bookmark-added",
|
||||
"bookmark-removed",
|
||||
"bookmark-moved",
|
||||
"bookmark-tags-changed",
|
||||
"bookmark-time-changed",
|
||||
"bookmark-title-changed",
|
||||
"bookmark-url-changed",
|
||||
|
@ -827,6 +828,7 @@ BookmarksTracker.prototype = {
|
|||
"bookmark-added",
|
||||
"bookmark-removed",
|
||||
"bookmark-moved",
|
||||
"bookmark-tags-changed",
|
||||
"bookmark-time-changed",
|
||||
"bookmark-title-changed",
|
||||
"bookmark-url-changed",
|
||||
|
@ -886,6 +888,7 @@ BookmarksTracker.prototype = {
|
|||
case "bookmark-removed":
|
||||
case "bookmark-moved":
|
||||
case "bookmark-guid-changed":
|
||||
case "bookmark-tags-changed":
|
||||
case "bookmark-time-changed":
|
||||
case "bookmark-title-changed":
|
||||
case "bookmark-url-changed":
|
||||
|
|
|
@ -336,26 +336,11 @@ var Bookmarks = Object.freeze({
|
|||
}),
|
||||
];
|
||||
|
||||
// If it's a tag, notify OnItemChanged to all bookmarks for this URL.
|
||||
// If it's a tag, notify bookmark-tags-changed event to all bookmarks for this URL.
|
||||
if (isTagging) {
|
||||
let observers = PlacesUtils.bookmarks.getObservers();
|
||||
for (let entry of await fetchBookmarksByURL(item, {
|
||||
concurrent: true,
|
||||
})) {
|
||||
notify(observers, "onItemChanged", [
|
||||
entry._id,
|
||||
"tags",
|
||||
false,
|
||||
"",
|
||||
PlacesUtils.toPRTime(entry.lastModified),
|
||||
entry.type,
|
||||
entry._parentId,
|
||||
entry.guid,
|
||||
entry.parentGuid,
|
||||
"",
|
||||
item.source,
|
||||
]);
|
||||
|
||||
notifications.push(
|
||||
new PlacesBookmarkTags({
|
||||
id: entry._id,
|
||||
|
@ -868,9 +853,6 @@ var Bookmarks = Object.freeze({
|
|||
|
||||
const notifications = [];
|
||||
|
||||
// Notify onItemChanged to listeners.
|
||||
let observers = PlacesUtils.bookmarks.getObservers();
|
||||
|
||||
// For lastModified, we only care about the original input, since we
|
||||
// should not notify implicit lastModified changes.
|
||||
if (
|
||||
|
@ -934,20 +916,6 @@ var Bookmarks = Object.freeze({
|
|||
{ tags: [updatedItem.title] },
|
||||
{ concurrent: true }
|
||||
)) {
|
||||
notify(observers, "onItemChanged", [
|
||||
entry._id,
|
||||
"tags",
|
||||
false,
|
||||
"",
|
||||
PlacesUtils.toPRTime(entry.lastModified),
|
||||
entry.type,
|
||||
entry._parentId,
|
||||
entry.guid,
|
||||
entry.parentGuid,
|
||||
"",
|
||||
updatedItem.source,
|
||||
]);
|
||||
|
||||
notifications.push(
|
||||
new PlacesBookmarkTags({
|
||||
id: entry._id,
|
||||
|
@ -1342,7 +1310,6 @@ var Bookmarks = Object.freeze({
|
|||
let notifications = [];
|
||||
|
||||
for (let item of removeItems) {
|
||||
let observers = PlacesUtils.bookmarks.getObservers();
|
||||
let isUntagging = item._grandParentId == PlacesUtils.tagsFolderId;
|
||||
let url = "";
|
||||
if (item.type == Bookmarks.TYPE_BOOKMARK) {
|
||||
|
@ -1368,20 +1335,6 @@ var Bookmarks = Object.freeze({
|
|||
for (let entry of await fetchBookmarksByURL(item, {
|
||||
concurrent: true,
|
||||
})) {
|
||||
notify(observers, "onItemChanged", [
|
||||
entry._id,
|
||||
"tags",
|
||||
false,
|
||||
"",
|
||||
PlacesUtils.toPRTime(entry.lastModified),
|
||||
entry.type,
|
||||
entry._parentId,
|
||||
entry.guid,
|
||||
entry.parentGuid,
|
||||
"",
|
||||
options.source,
|
||||
]);
|
||||
|
||||
notifications.push(
|
||||
new PlacesBookmarkTags({
|
||||
id: entry._id,
|
||||
|
@ -1897,38 +1850,6 @@ var Bookmarks = Object.freeze({
|
|||
|
||||
// Globals.
|
||||
|
||||
/**
|
||||
* Sends a bookmarks notification through the given observers.
|
||||
*
|
||||
* @param {Array} observers
|
||||
* array of nsINavBookmarkObserver objects.
|
||||
* @param {String} notification
|
||||
* the notification name.
|
||||
* @param {Array} [args]
|
||||
* array of arguments to pass to the notification.
|
||||
* @param {Object} [information]
|
||||
* Information about the notification, so we can filter based
|
||||
* based on the observer's preferences.
|
||||
*/
|
||||
function notify(observers, notification, args = [], information = {}) {
|
||||
for (let observer of observers) {
|
||||
if (information.isTagging && observer.skipTags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
information.isDescendantRemoval &&
|
||||
!PlacesUtils.bookmarks.userContentRoots.includes(information.parentGuid)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
observer[notification](...args);
|
||||
} catch (ex) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Update implementation.
|
||||
|
||||
/**
|
||||
|
@ -3330,7 +3251,6 @@ var removeFoldersContents = async function(db, folderGuids, options) {
|
|||
|
||||
// Notify listeners in reverse order to serve children before parents.
|
||||
let { source = Bookmarks.SOURCES.DEFAULT } = options;
|
||||
let observers = PlacesUtils.bookmarks.getObservers();
|
||||
let notifications = [];
|
||||
for (let item of itemsRemoved.reverse()) {
|
||||
let isUntagging = item._grandParentId == PlacesUtils.tagsFolderId;
|
||||
|
@ -3357,20 +3277,6 @@ var removeFoldersContents = async function(db, folderGuids, options) {
|
|||
|
||||
if (isUntagging) {
|
||||
for (let entry of await fetchBookmarksByURL(item, true)) {
|
||||
notify(observers, "onItemChanged", [
|
||||
entry._id,
|
||||
"tags",
|
||||
false,
|
||||
"",
|
||||
PlacesUtils.toPRTime(entry.lastModified),
|
||||
entry.type,
|
||||
entry._parentId,
|
||||
entry.guid,
|
||||
entry.parentGuid,
|
||||
"",
|
||||
source,
|
||||
]);
|
||||
|
||||
notifications.push(
|
||||
new PlacesBookmarkTags({
|
||||
id: entry._id,
|
||||
|
|
|
@ -457,14 +457,6 @@ nsNavBookmarks::InsertBookmark(int64_t aFolder, nsIURI* aURI, int32_t aIndex,
|
|||
for (uint32_t i = 0; i < bookmarks.Length(); ++i) {
|
||||
// Check that bookmarks doesn't include the current tag itemId.
|
||||
MOZ_ASSERT(bookmarks[i].id != *aNewBookmarkId);
|
||||
|
||||
NOTIFY_BOOKMARKS_OBSERVERS(
|
||||
mCanNotify, mObservers,
|
||||
OnItemChanged(bookmarks[i].id, "tags"_ns, false, ""_ns,
|
||||
bookmarks[i].lastModified, TYPE_BOOKMARK,
|
||||
bookmarks[i].parentId, bookmarks[i].guid,
|
||||
bookmarks[i].parentGuid, ""_ns, aSource));
|
||||
|
||||
RefPtr<PlacesBookmarkTags> tagsChanged = new PlacesBookmarkTags();
|
||||
tagsChanged->mId = bookmarks[i].id;
|
||||
tagsChanged->mItemType = TYPE_BOOKMARK;
|
||||
|
@ -599,13 +591,6 @@ nsNavBookmarks::RemoveItem(int64_t aItemId, uint16_t aSource) {
|
|||
uri->GetSpec(utf8spec);
|
||||
|
||||
for (uint32_t i = 0; i < bookmarks.Length(); ++i) {
|
||||
NOTIFY_BOOKMARKS_OBSERVERS(
|
||||
mCanNotify, mObservers,
|
||||
OnItemChanged(bookmarks[i].id, "tags"_ns, false, ""_ns,
|
||||
bookmarks[i].lastModified, TYPE_BOOKMARK,
|
||||
bookmarks[i].parentId, bookmarks[i].guid,
|
||||
bookmarks[i].parentGuid, ""_ns, aSource));
|
||||
|
||||
RefPtr<PlacesBookmarkTags> tagsChanged = new PlacesBookmarkTags();
|
||||
tagsChanged->mId = bookmarks[i].id;
|
||||
tagsChanged->mItemType = TYPE_BOOKMARK;
|
||||
|
@ -920,13 +905,6 @@ nsresult nsNavBookmarks::RemoveFolderChildren(int64_t aFolderId,
|
|||
uri->GetSpec(utf8spec);
|
||||
|
||||
for (uint32_t i = 0; i < bookmarks.Length(); ++i) {
|
||||
NOTIFY_BOOKMARKS_OBSERVERS(
|
||||
mCanNotify, mObservers,
|
||||
OnItemChanged(bookmarks[i].id, "tags"_ns, false, ""_ns,
|
||||
bookmarks[i].lastModified, TYPE_BOOKMARK,
|
||||
bookmarks[i].parentId, bookmarks[i].guid,
|
||||
bookmarks[i].parentGuid, ""_ns, aSource));
|
||||
|
||||
RefPtr<PlacesBookmarkTags> tagsChanged = new PlacesBookmarkTags();
|
||||
tagsChanged->mId = bookmarks[i].id;
|
||||
tagsChanged->mItemType = TYPE_BOOKMARK;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "mozilla/dom/PlacesVisitRemoved.h"
|
||||
#include "mozilla/dom/PlacesVisitTitle.h"
|
||||
#include "mozilla/dom/PlacesBookmarkMoved.h"
|
||||
#include "mozilla/dom/PlacesBookmarkTags.h"
|
||||
#include "mozilla/dom/PlacesBookmarkTime.h"
|
||||
#include "mozilla/dom/PlacesBookmarkTitle.h"
|
||||
#include "mozilla/dom/PlacesBookmarkUrl.h"
|
||||
|
@ -2483,25 +2484,6 @@ nsNavHistoryQueryResultNode::OnItemChanged(
|
|||
return Refresh();
|
||||
}
|
||||
|
||||
// Some node could observe both bookmarks and history. But a node observing
|
||||
// only history should never get a bookmark notification.
|
||||
NS_WARNING_ASSERTION(
|
||||
mResult && mResult->mIsBookmarksObserver,
|
||||
"history observers should not get OnItemChanged, but should get the "
|
||||
"corresponding history notifications instead");
|
||||
|
||||
// Tags in history queries are a special case since tags are per uri and
|
||||
// we filter tags based on searchterms.
|
||||
if (aItemType == nsINavBookmarksService::TYPE_BOOKMARK &&
|
||||
aProperty.EqualsLiteral("tags")) {
|
||||
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
|
||||
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = bookmarks->GetBookmarkURI(aItemId, getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = NotifyIfTagsChanged(uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2522,6 +2504,19 @@ nsresult nsNavHistoryQueryResultNode::OnItemMoved(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNavHistoryQueryResultNode::OnItemTagsChanged(int64_t aItemId,
|
||||
const nsAString& aURL) {
|
||||
nsresult rv = nsNavHistoryResultNode::OnItemTagsChanged(aItemId, aURL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), aURL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = NotifyIfTagsChanged(uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNavHistoryQueryResultNode::OnItemUrlChanged(int64_t aItemId,
|
||||
const nsACString& aGUID,
|
||||
const nsACString& aURL,
|
||||
|
@ -3193,6 +3188,24 @@ nsresult nsNavHistoryFolderResultNode::OnItemRemoved(
|
|||
return RemoveChildAt(index);
|
||||
}
|
||||
|
||||
nsresult nsNavHistoryResultNode::OnItemTagsChanged(int64_t aItemId,
|
||||
const nsAString& aURL) {
|
||||
if (aItemId != mItemId) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mTags.SetIsVoid(true);
|
||||
|
||||
bool shouldNotify = !mParent || mParent->AreChildrenVisible();
|
||||
if (shouldNotify) {
|
||||
nsNavHistoryResult* result = GetResult();
|
||||
NS_ENSURE_STATE(result);
|
||||
NOTIFY_RESULT_OBSERVERS(result, NodeTagsChanged(this));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNavHistoryResultNode::OnItemTimeChanged(int64_t aItemId,
|
||||
const nsACString& aGUID,
|
||||
PRTime aDateAdded,
|
||||
|
@ -3305,9 +3318,6 @@ nsNavHistoryResultNode::OnItemChanged(
|
|||
NOTIFY_RESULT_OBSERVERS(
|
||||
result, NodeHistoryDetailsChanged(this, oldTime, mAccessCount));
|
||||
}
|
||||
} else if (aProperty.EqualsLiteral("tags")) {
|
||||
mTags.SetIsVoid(true);
|
||||
if (shouldNotify) NOTIFY_RESULT_OBSERVERS(result, NodeTagsChanged(this));
|
||||
} else if (aProperty.EqualsLiteral("keyword")) {
|
||||
if (shouldNotify)
|
||||
NOTIFY_RESULT_OBSERVERS(result, NodeKeywordChanged(this, aNewValue));
|
||||
|
@ -3583,7 +3593,7 @@ nsNavHistoryResult::~nsNavHistoryResult() {
|
|||
}
|
||||
|
||||
void nsNavHistoryResult::StopObserving() {
|
||||
AutoTArray<PlacesEventType, 10> events;
|
||||
AutoTArray<PlacesEventType, 11> events;
|
||||
events.AppendElement(PlacesEventType::Favicon_changed);
|
||||
if (mIsBookmarksObserver) {
|
||||
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
|
||||
|
@ -3594,6 +3604,7 @@ void nsNavHistoryResult::StopObserving() {
|
|||
events.AppendElement(PlacesEventType::Bookmark_added);
|
||||
events.AppendElement(PlacesEventType::Bookmark_removed);
|
||||
events.AppendElement(PlacesEventType::Bookmark_moved);
|
||||
events.AppendElement(PlacesEventType::Bookmark_tags_changed);
|
||||
events.AppendElement(PlacesEventType::Bookmark_time_changed);
|
||||
events.AppendElement(PlacesEventType::Bookmark_title_changed);
|
||||
events.AppendElement(PlacesEventType::Bookmark_url_changed);
|
||||
|
@ -3717,10 +3728,11 @@ void nsNavHistoryResult::EnsureIsObservingBookmarks() {
|
|||
return;
|
||||
}
|
||||
bookmarks->AddObserver(this, true);
|
||||
AutoTArray<PlacesEventType, 7> events;
|
||||
AutoTArray<PlacesEventType, 8> events;
|
||||
events.AppendElement(PlacesEventType::Bookmark_added);
|
||||
events.AppendElement(PlacesEventType::Bookmark_removed);
|
||||
events.AppendElement(PlacesEventType::Bookmark_moved);
|
||||
events.AppendElement(PlacesEventType::Bookmark_tags_changed);
|
||||
events.AppendElement(PlacesEventType::Bookmark_time_changed);
|
||||
events.AppendElement(PlacesEventType::Bookmark_title_changed);
|
||||
events.AppendElement(PlacesEventType::Bookmark_url_changed);
|
||||
|
@ -4291,6 +4303,18 @@ void nsNavHistoryResult::HandlePlacesEvent(const PlacesEventSequence& aEvents) {
|
|||
item->mParentGuid, item->mSource, url));
|
||||
break;
|
||||
}
|
||||
case PlacesEventType::Bookmark_tags_changed: {
|
||||
const dom::PlacesBookmarkTags* tagsEvent =
|
||||
event->AsPlacesBookmarkTags();
|
||||
if (NS_WARN_IF(!tagsEvent)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ENUMERATE_BOOKMARK_CHANGED_OBSERVERS(
|
||||
tagsEvent->mParentGuid, tagsEvent->mId,
|
||||
OnItemTagsChanged(tagsEvent->mId, tagsEvent->mUrl));
|
||||
break;
|
||||
}
|
||||
case PlacesEventType::Bookmark_time_changed: {
|
||||
const dom::PlacesBookmarkTime* timeEvent =
|
||||
event->AsPlacesBookmarkTime();
|
||||
|
|
|
@ -314,6 +314,7 @@ class nsNavHistoryResultNode : public nsINavHistoryResultNode {
|
|||
|
||||
virtual void OnRemoving();
|
||||
|
||||
nsresult OnItemTagsChanged(int64_t aItemId, const nsAString& aURL);
|
||||
nsresult OnItemTimeChanged(int64_t aItemId, const nsACString& aGUID,
|
||||
PRTime aDateAdded, PRTime aLastModified);
|
||||
nsresult OnItemTitleChanged(int64_t aItemId, const nsACString& aGUID,
|
||||
|
@ -700,6 +701,7 @@ class nsNavHistoryQueryResultNode final
|
|||
const nsACString& aOldParentGUID,
|
||||
const nsACString& aNewParentGUID, uint16_t aSource,
|
||||
const nsACString& aURI);
|
||||
nsresult OnItemTagsChanged(int64_t aItemId, const nsAString& aURL);
|
||||
nsresult OnItemUrlChanged(int64_t aItemId, const nsACString& aGUID,
|
||||
const nsACString& aURL, PRTime aLastModified);
|
||||
|
||||
|
|
|
@ -123,6 +123,19 @@ function expectPlacesObserverNotifications(
|
|||
isTagging: event.isTagging,
|
||||
});
|
||||
break;
|
||||
case "bookmark-tags-changed":
|
||||
notifications.push({
|
||||
type: event.type,
|
||||
id: event.id,
|
||||
itemType: event.itemType,
|
||||
url: event.url,
|
||||
guid: event.guid,
|
||||
parentGuid: event.parentGuid,
|
||||
lastModified: new Date(event.lastModified),
|
||||
source: event.source,
|
||||
isTagging: event.isTagging,
|
||||
});
|
||||
break;
|
||||
case "bookmark-time-changed":
|
||||
notifications.push({
|
||||
type: event.type,
|
||||
|
|
|
@ -150,15 +150,16 @@ add_task(async function insert_bookmark_tag_notification() {
|
|||
url: new URL("http://tag.example.com/"),
|
||||
});
|
||||
let itemId = await PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = await PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
let tagFolder = await PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.tagsGuid,
|
||||
title: "tag",
|
||||
});
|
||||
let placesObserver = expectPlacesObserverNotifications(["bookmark-added"]);
|
||||
let bookmarksObserver = expectNotifications();
|
||||
const observer = expectPlacesObserverNotifications([
|
||||
"bookmark-added",
|
||||
"bookmark-tags-changed",
|
||||
]);
|
||||
let tag = await PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: tagFolder.guid,
|
||||
|
@ -167,7 +168,7 @@ add_task(async function insert_bookmark_tag_notification() {
|
|||
let tagId = await PlacesUtils.promiseItemId(tag.guid);
|
||||
let tagParentId = await PlacesUtils.promiseItemId(tag.parentGuid);
|
||||
|
||||
placesObserver.check([
|
||||
observer.check([
|
||||
{
|
||||
type: "bookmark-added",
|
||||
id: tagId,
|
||||
|
@ -182,24 +183,16 @@ add_task(async function insert_bookmark_tag_notification() {
|
|||
source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
|
||||
isTagging: true,
|
||||
},
|
||||
]);
|
||||
|
||||
bookmarksObserver.check([
|
||||
{
|
||||
name: "onItemChanged",
|
||||
arguments: [
|
||||
itemId,
|
||||
"tags",
|
||||
false,
|
||||
"",
|
||||
PlacesUtils.toPRTime(bm.lastModified),
|
||||
bm.type,
|
||||
parentId,
|
||||
bm.guid,
|
||||
bm.parentGuid,
|
||||
"",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT,
|
||||
],
|
||||
type: "bookmark-tags-changed",
|
||||
id: itemId,
|
||||
itemType: bm.type,
|
||||
url: bm.url,
|
||||
guid: bm.guid,
|
||||
parentGuid: bm.parentGuid,
|
||||
lastModified: bm.lastModified,
|
||||
source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
|
||||
isTagging: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -545,7 +538,6 @@ add_task(async function remove_bookmark_tag_notification() {
|
|||
url: new URL("http://untag.example.com/"),
|
||||
});
|
||||
let itemId = await PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = await PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
let tagFolder = await PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
|
@ -560,11 +552,13 @@ add_task(async function remove_bookmark_tag_notification() {
|
|||
let tagId = await PlacesUtils.promiseItemId(tag.guid);
|
||||
let tagParentId = await PlacesUtils.promiseItemId(tag.parentGuid);
|
||||
|
||||
let placesObserver = expectPlacesObserverNotifications(["bookmark-removed"]);
|
||||
let observer = expectNotifications();
|
||||
const observer = expectPlacesObserverNotifications([
|
||||
"bookmark-removed",
|
||||
"bookmark-tags-changed",
|
||||
]);
|
||||
await PlacesUtils.bookmarks.remove(tag.guid);
|
||||
|
||||
placesObserver.check([
|
||||
observer.check([
|
||||
{
|
||||
type: "bookmark-removed",
|
||||
id: tagId,
|
||||
|
@ -577,23 +571,16 @@ add_task(async function remove_bookmark_tag_notification() {
|
|||
itemType: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
isTagging: true,
|
||||
},
|
||||
]);
|
||||
observer.check([
|
||||
{
|
||||
name: "onItemChanged",
|
||||
arguments: [
|
||||
itemId,
|
||||
"tags",
|
||||
false,
|
||||
"",
|
||||
PlacesUtils.toPRTime(bm.lastModified),
|
||||
bm.type,
|
||||
parentId,
|
||||
bm.guid,
|
||||
bm.parentGuid,
|
||||
"",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT,
|
||||
],
|
||||
type: "bookmark-tags-changed",
|
||||
id: itemId,
|
||||
itemType: bm.type,
|
||||
url: bm.url,
|
||||
guid: bm.guid,
|
||||
parentGuid: bm.parentGuid,
|
||||
lastModified: bm.lastModified,
|
||||
source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
|
||||
isTagging: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -993,35 +980,3 @@ add_task(async function update_notitle_notification() {
|
|||
},
|
||||
]);
|
||||
});
|
||||
|
||||
function expectNotifications() {
|
||||
let notifications = [];
|
||||
let observer = new Proxy(NavBookmarkObserver, {
|
||||
get(target, name) {
|
||||
if (name == "check") {
|
||||
PlacesUtils.bookmarks.removeObserver(observer);
|
||||
return expectedNotifications =>
|
||||
Assert.deepEqual(notifications, expectedNotifications);
|
||||
}
|
||||
|
||||
if (name.startsWith("onItem")) {
|
||||
return (...origArgs) => {
|
||||
let args = Array.from(origArgs, arg => {
|
||||
if (arg && arg instanceof Ci.nsIURI) {
|
||||
return new URL(arg.spec);
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
notifications.push({ name, arguments: args });
|
||||
};
|
||||
}
|
||||
|
||||
if (name in target) {
|
||||
return target[name];
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
PlacesUtils.bookmarks.addObserver(observer);
|
||||
return observer;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that each nsINavBookmarksObserver method gets the correct input.
|
||||
// Tests that each bookmark event gets the correct input.
|
||||
|
||||
var gUnfiledFolderId;
|
||||
|
||||
|
@ -35,34 +35,9 @@ var gBookmarksObserver = {
|
|||
}
|
||||
},
|
||||
|
||||
validate(aMethodName, aArguments) {
|
||||
Assert.equal(this.expected[0].name, aMethodName);
|
||||
|
||||
let args = this.expected.shift().args;
|
||||
Assert.equal(aArguments.length, args.length);
|
||||
for (let i = 0; i < aArguments.length; i++) {
|
||||
Assert.ok(
|
||||
args[i].check(aArguments[i]),
|
||||
aMethodName + "(args[" + i + "]: " + args[i].name + ")"
|
||||
);
|
||||
}
|
||||
|
||||
if (this.expected.length === 0) {
|
||||
this.deferred.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
handlePlacesEvents(events) {
|
||||
this.validateEvents(events);
|
||||
},
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
onItemChanged() {
|
||||
return this.validate("onItemChanged", arguments);
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
QueryInterface: ChromeUtils.generateQI(["nsINavBookmarkObserver"]),
|
||||
};
|
||||
|
||||
var gBookmarkSkipObserver = {
|
||||
|
@ -88,29 +63,12 @@ var gBookmarkSkipObserver = {
|
|||
}
|
||||
},
|
||||
|
||||
validate(aMethodName) {
|
||||
Assert.equal(this.expected.shift(), aMethodName);
|
||||
if (this.expected.length === 0) {
|
||||
this.deferred.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
handlePlacesEvents(events) {
|
||||
this.validateEvents(events);
|
||||
},
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
onItemChanged() {
|
||||
return this.validate("onItemChanged", arguments);
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
QueryInterface: ChromeUtils.generateQI(["nsINavBookmarkObserver"]),
|
||||
};
|
||||
|
||||
add_task(async function setup() {
|
||||
PlacesUtils.bookmarks.addObserver(gBookmarksObserver);
|
||||
PlacesUtils.bookmarks.addObserver(gBookmarkSkipObserver);
|
||||
gUnfiledFolderId = await PlacesUtils.promiseItemId(
|
||||
PlacesUtils.bookmarks.unfiledGuid
|
||||
);
|
||||
|
@ -125,6 +83,7 @@ add_task(async function setup() {
|
|||
"bookmark-added",
|
||||
"bookmark-removed",
|
||||
"bookmark-moved",
|
||||
"bookmark-tags-changed",
|
||||
"bookmark-title-changed",
|
||||
],
|
||||
gBookmarksObserver.handlePlacesEvents
|
||||
|
@ -134,6 +93,7 @@ add_task(async function setup() {
|
|||
"bookmark-added",
|
||||
"bookmark-removed",
|
||||
"bookmark-moved",
|
||||
"bookmark-tags-changed",
|
||||
"bookmark-title-changed",
|
||||
],
|
||||
gBookmarkSkipObserver.handlePlacesEvents
|
||||
|
@ -268,7 +228,7 @@ add_task(async function bookmarkItemAdded_folder() {
|
|||
await promise;
|
||||
});
|
||||
|
||||
add_task(async function onItemChanged_title_bookmark() {
|
||||
add_task(async function bookmarkTitleChanged() {
|
||||
let bm = await PlacesUtils.bookmarks.fetch({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 0,
|
||||
|
@ -304,7 +264,7 @@ add_task(async function onItemChanged_title_bookmark() {
|
|||
await promise;
|
||||
});
|
||||
|
||||
add_task(async function onItemChanged_tags_bookmark() {
|
||||
add_task(async function bookmarkTagsChanged() {
|
||||
let bm = await PlacesUtils.bookmarks.fetch({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 0,
|
||||
|
@ -312,7 +272,10 @@ add_task(async function onItemChanged_tags_bookmark() {
|
|||
let uri = Services.io.newURI(bm.url.href);
|
||||
const TAG = "tag";
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup(["onItemChanged", "onItemChanged"]),
|
||||
gBookmarkSkipObserver.setup([
|
||||
"bookmark-tags-changed",
|
||||
"bookmark-tags-changed",
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{
|
||||
eventType: "bookmark-added", // This is the tag folder.
|
||||
|
@ -371,18 +334,13 @@ add_task(async function onItemChanged_tags_bookmark() {
|
|||
],
|
||||
},
|
||||
{
|
||||
name: "onItemChanged",
|
||||
eventType: "bookmark-tags-changed",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof v == "number" && v > 0 },
|
||||
{ name: "property", check: v => v === "tags" },
|
||||
{ name: "isAnno", check: v => v === false },
|
||||
{ name: "newValue", check: v => v === "" },
|
||||
{ name: "lastModified", check: v => typeof v == "number" && v > 0 },
|
||||
{ name: "id", check: v => typeof v == "number" && v > 0 },
|
||||
{
|
||||
name: "itemType",
|
||||
check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
},
|
||||
{ name: "parentId", check: v => v === gUnfiledFolderId },
|
||||
{
|
||||
name: "guid",
|
||||
check: v => typeof v == "string" && PlacesUtils.isValidGuid(v),
|
||||
|
@ -391,12 +349,16 @@ add_task(async function onItemChanged_tags_bookmark() {
|
|||
name: "parentGuid",
|
||||
check: v => typeof v == "string" && PlacesUtils.isValidGuid(v),
|
||||
},
|
||||
{ name: "oldValue", check: v => typeof v == "string" },
|
||||
{ name: "lastModified", check: v => typeof v == "number" && v > 0 },
|
||||
{
|
||||
name: "source",
|
||||
check: v =>
|
||||
Object.values(PlacesUtils.bookmarks.SOURCES).includes(v),
|
||||
},
|
||||
{
|
||||
name: "isTagging",
|
||||
check: v => v === false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -425,20 +387,14 @@ add_task(async function onItemChanged_tags_bookmark() {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "onItemChanged",
|
||||
eventType: "bookmark-tags-changed",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof v == "number" && v > 0 },
|
||||
{ name: "property", check: v => v === "tags" },
|
||||
{ name: "isAnno", check: v => v === false },
|
||||
{ name: "newValue", check: v => v === "" },
|
||||
{ name: "lastModified", check: v => typeof v == "number" && v > 0 },
|
||||
{ name: "id", check: v => typeof v == "number" && v > 0 },
|
||||
{
|
||||
name: "itemType",
|
||||
check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
},
|
||||
{ name: "parentId", check: v => v === gUnfiledFolderId },
|
||||
{
|
||||
name: "guid",
|
||||
check: v => typeof v == "string" && PlacesUtils.isValidGuid(v),
|
||||
|
@ -447,12 +403,16 @@ add_task(async function onItemChanged_tags_bookmark() {
|
|||
name: "parentGuid",
|
||||
check: v => typeof v == "string" && PlacesUtils.isValidGuid(v),
|
||||
},
|
||||
{ name: "oldValue", check: v => typeof v == "string" },
|
||||
{ name: "lastModified", check: v => typeof v == "number" && v > 0 },
|
||||
{
|
||||
name: "source",
|
||||
check: v =>
|
||||
Object.values(PlacesUtils.bookmarks.SOURCES).includes(v),
|
||||
},
|
||||
{
|
||||
name: "isTagging",
|
||||
check: v => v === false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -952,14 +912,24 @@ add_task(async function bookmarkItemRemoved_folder_recursive() {
|
|||
});
|
||||
|
||||
add_task(function cleanup() {
|
||||
PlacesUtils.bookmarks.removeObserver(gBookmarksObserver);
|
||||
PlacesUtils.bookmarks.removeObserver(gBookmarkSkipObserver);
|
||||
PlacesUtils.observers.removeListener(
|
||||
["bookmark-added"],
|
||||
[
|
||||
"bookmark-added",
|
||||
"bookmark-removed",
|
||||
"bookmark-moved",
|
||||
"bookmark-tags-changed",
|
||||
"bookmark-title-changed",
|
||||
],
|
||||
gBookmarksObserver.handlePlacesEvents
|
||||
);
|
||||
PlacesUtils.observers.removeListener(
|
||||
["bookmark-added"],
|
||||
[
|
||||
"bookmark-added",
|
||||
"bookmark-removed",
|
||||
"bookmark-moved",
|
||||
"bookmark-tags-changed",
|
||||
"bookmark-title-changed",
|
||||
],
|
||||
gBookmarkSkipObserver.handlePlacesEvents
|
||||
);
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// This test checks that changing a tag for a bookmark with multiple tags
|
||||
// notifies OnItemChanged("tags") only once, and not once per tag.
|
||||
// notifies bookmark-tags-changed event only once, and not once per tag.
|
||||
|
||||
add_task(async function run_test() {
|
||||
let tags = ["a", "b", "c"];
|
||||
|
@ -18,24 +18,7 @@ add_task(async function run_test() {
|
|||
let promise = PromiseUtils.defer();
|
||||
|
||||
let bookmarksObserver = {
|
||||
QueryInterface: ChromeUtils.generateQI(["nsINavBookmarkObserver"]),
|
||||
|
||||
_changedCount: 0,
|
||||
onItemChanged(
|
||||
aItemId,
|
||||
aProperty,
|
||||
aIsAnnotationProperty,
|
||||
aValue,
|
||||
aLastModified,
|
||||
aItemType,
|
||||
aParentId,
|
||||
aGuid
|
||||
) {
|
||||
if (aProperty == "tags") {
|
||||
Assert.equal(aGuid, bookmark.guid);
|
||||
this._changedCount++;
|
||||
}
|
||||
},
|
||||
handlePlacesEvents(events) {
|
||||
for (let event of events) {
|
||||
switch (event.type) {
|
||||
|
@ -48,16 +31,20 @@ add_task(async function run_test() {
|
|||
Assert.equal(this._changedCount, 2);
|
||||
promise.resolve();
|
||||
}
|
||||
break;
|
||||
case "bookmark-tags-changed":
|
||||
Assert.equal(event.guid, bookmark.guid);
|
||||
this._changedCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
PlacesUtils.bookmarks.addObserver(bookmarksObserver);
|
||||
bookmarksObserver.handlePlacesEvents = bookmarksObserver.handlePlacesEvents.bind(
|
||||
bookmarksObserver
|
||||
);
|
||||
PlacesUtils.observers.addListener(
|
||||
["bookmark-removed"],
|
||||
["bookmark-removed", "bookmark-tags-changed"],
|
||||
bookmarksObserver.handlePlacesEvents
|
||||
);
|
||||
|
|
@ -39,6 +39,7 @@ skip-if = os == "linux" # Bug 821781
|
|||
[test_1606731.js]
|
||||
[test_asyncExecuteLegacyQueries.js]
|
||||
[test_async_transactions.js]
|
||||
[test_bookmark-tags-changed_frequency.js]
|
||||
[test_bookmarks_json.js]
|
||||
[test_bookmarks_json_corrupt.js]
|
||||
[test_bookmarks_html.js]
|
||||
|
@ -75,7 +76,6 @@ support-files = noRoot.sqlite
|
|||
[test_multi_word_tags.js]
|
||||
[test_nsINavHistoryViewer.js]
|
||||
[test_null_interfaces.js]
|
||||
[test_onItemChanged_tags.js]
|
||||
[test_origins.js]
|
||||
[test_origins_parsing.js]
|
||||
[test_pageGuid_bookmarkGuid.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче