mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 707955 - Tags should avoid results overhead.
r=dietrich
This commit is contained in:
parent
faecbfc0c2
commit
e6acfd675f
@ -61,29 +61,6 @@ function TaggingService() {
|
||||
}
|
||||
|
||||
TaggingService.prototype = {
|
||||
/**
|
||||
* If there's no tag with the given name or id, null is returned;
|
||||
*/
|
||||
_getTagResult: function TS__getTagResult(aTagNameOrId) {
|
||||
if (!aTagNameOrId)
|
||||
throw Cr.NS_ERROR_INVALID_ARG;
|
||||
|
||||
var tagId = null;
|
||||
if (typeof(aTagNameOrId) == "string")
|
||||
tagId = this._getItemIdForTag(aTagNameOrId);
|
||||
else
|
||||
tagId = aTagNameOrId;
|
||||
|
||||
if (tagId == -1)
|
||||
return null;
|
||||
|
||||
var options = PlacesUtils.history.getNewQueryOptions();
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([tagId], 1);
|
||||
var result = PlacesUtils.history.executeQuery(query, options);
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a tag container under the tags-root with the given name.
|
||||
*
|
||||
@ -116,11 +93,24 @@ TaggingService.prototype = {
|
||||
var tagId = this._getItemIdForTag(aTagName);
|
||||
if (tagId == -1)
|
||||
return -1;
|
||||
var bookmarkIds = PlacesUtils.bookmarks.getBookmarkIdsForURI(aURI);
|
||||
for (var i=0; i < bookmarkIds.length; i++) {
|
||||
var parent = PlacesUtils.bookmarks.getFolderIdForItem(bookmarkIds[i]);
|
||||
if (parent == tagId)
|
||||
return bookmarkIds[i];
|
||||
// Using bookmarks service API for this would be a pain.
|
||||
// Until tags implementation becomes sane, go the query way.
|
||||
let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT id FROM moz_bookmarks "
|
||||
+ "WHERE parent = :tag_id "
|
||||
+ "AND fk = (SELECT id FROM moz_places WHERE url = :page_url)"
|
||||
);
|
||||
stmt.params.tag_id = tagId;
|
||||
stmt.params.page_url = aURI.spec;
|
||||
try {
|
||||
if (stmt.executeStep()) {
|
||||
return stmt.row.id;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
@ -223,14 +213,24 @@ TaggingService.prototype = {
|
||||
* the itemId of the tag element under the tags root
|
||||
*/
|
||||
_removeTagIfEmpty: function TS__removeTagIfEmpty(aTagId) {
|
||||
var result = this._getTagResult(aTagId);
|
||||
if (!result)
|
||||
return;
|
||||
var node = PlacesUtils.asContainer(result.root);
|
||||
node.containerOpen = true;
|
||||
var cc = node.childCount;
|
||||
node.containerOpen = false;
|
||||
if (cc == 0) {
|
||||
let count = 0;
|
||||
let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT count(*) AS count FROM moz_bookmarks "
|
||||
+ "WHERE parent = :tag_id"
|
||||
);
|
||||
stmt.params.tag_id = aTagId;
|
||||
try {
|
||||
if (stmt.executeStep()) {
|
||||
count = stmt.row.count;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
PlacesUtils.bookmarks.removeItem(aTagId);
|
||||
}
|
||||
},
|
||||
@ -271,27 +271,34 @@ TaggingService.prototype = {
|
||||
},
|
||||
|
||||
// nsITaggingService
|
||||
getURIsForTag: function TS_getURIsForTag(aTag) {
|
||||
if (!aTag || aTag.length == 0)
|
||||
getURIsForTag: function TS_getURIsForTag(aTagName) {
|
||||
if (!aTagName || aTagName.length == 0)
|
||||
throw Cr.NS_ERROR_INVALID_ARG;
|
||||
|
||||
var uris = [];
|
||||
var tagResult = this._getTagResult(aTag);
|
||||
if (tagResult) {
|
||||
var tagNode = tagResult.root;
|
||||
tagNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
tagNode.containerOpen = true;
|
||||
var cc = tagNode.childCount;
|
||||
for (var i = 0; i < cc; i++) {
|
||||
let uris = [];
|
||||
let tagId = this._getItemIdForTag(aTagName);
|
||||
if (tagId == -1)
|
||||
return uris;
|
||||
|
||||
let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT h.url FROM moz_places h "
|
||||
+ "JOIN moz_bookmarks b ON b.fk = h.id "
|
||||
+ "WHERE b.parent = :tag_id "
|
||||
);
|
||||
stmt.params.tag_id = tagId;
|
||||
try {
|
||||
while (stmt.executeStep()) {
|
||||
try {
|
||||
uris.push(Services.io.newURI(tagNode.getChild(i).uri, null, null));
|
||||
} catch (ex) {
|
||||
// This is an invalid node, tags should only contain valid uri nodes.
|
||||
// continue to next node.
|
||||
}
|
||||
uris.push(Services.io.newURI(stmt.row.url, null, null));
|
||||
} catch (ex) {}
|
||||
}
|
||||
tagNode.containerOpen = false;
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
return uris;
|
||||
},
|
||||
|
||||
@ -321,18 +328,21 @@ TaggingService.prototype = {
|
||||
get _tagFolders() {
|
||||
if (!this.__tagFolders) {
|
||||
this.__tagFolders = [];
|
||||
var options = PlacesUtils.history.getNewQueryOptions();
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([PlacesUtils.tagsFolderId], 1);
|
||||
var tagsResult = PlacesUtils.history.executeQuery(query, options);
|
||||
var root = tagsResult.root;
|
||||
root.containerOpen = true;
|
||||
var cc = root.childCount;
|
||||
for (var i=0; i < cc; i++) {
|
||||
var child = root.getChild(i);
|
||||
this.__tagFolders[child.itemId] = child.title;
|
||||
|
||||
let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT id, title FROM moz_bookmarks WHERE parent = :tags_root "
|
||||
);
|
||||
stmt.params.tags_root = PlacesUtils.tagsFolderId;
|
||||
try {
|
||||
while (stmt.executeStep()) {
|
||||
this.__tagFolders[stmt.row.id] = stmt.row.title;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
return this.__tagFolders;
|
||||
@ -365,29 +375,47 @@ TaggingService.prototype = {
|
||||
|
||||
/**
|
||||
* If the only bookmark items associated with aURI are contained in tag
|
||||
* folders, returns the IDs of those tag folders. This can be the case if
|
||||
* folders, returns the IDs of those items. This can be the case if
|
||||
* the URI was bookmarked and tagged at some point, but the bookmark was
|
||||
* removed, leaving only the bookmark items in tag folders. Returns null
|
||||
* if the URI is either properly bookmarked or not tagged.
|
||||
* removed, leaving only the bookmark items in tag folders. If the URI is
|
||||
* either properly bookmarked or not tagged just returns and empty array.
|
||||
*
|
||||
* @param aURI
|
||||
* A URI (string) that may or may not be bookmarked
|
||||
* @returns null or an array of tag IDs
|
||||
* @returns an array of item ids
|
||||
*/
|
||||
_getTagsIfUnbookmarkedURI: function TS__getTagsIfUnbookmarkedURI(aURI) {
|
||||
var tagIds = [];
|
||||
_getTaggedItemIdsIfUnbookmarkedURI:
|
||||
function TS__getTaggedItemIdsIfUnbookmarkedURI(aURI) {
|
||||
var itemIds = [];
|
||||
var isBookmarked = false;
|
||||
var itemIds = PlacesUtils.bookmarks.getBookmarkIdsForURI(aURI);
|
||||
|
||||
for (let i = 0; !isBookmarked && i < itemIds.length; i++) {
|
||||
var parentId = PlacesUtils.bookmarks.getFolderIdForItem(itemIds[i]);
|
||||
if (this._tagFolders[parentId])
|
||||
tagIds.push(parentId);
|
||||
else
|
||||
isBookmarked = true;
|
||||
// Using bookmarks service API for this would be a pain.
|
||||
// Until tags implementation becomes sane, go the query way.
|
||||
let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT id, parent "
|
||||
+ "FROM moz_bookmarks "
|
||||
+ "WHERE fk = (SELECT id FROM moz_places WHERE url = :page_url)"
|
||||
);
|
||||
stmt.params.page_url = aURI.spec;
|
||||
try {
|
||||
while (stmt.executeStep() && !isBookmarked) {
|
||||
if (this._tagFolders[stmt.row.parent]) {
|
||||
// This is a tag entry.
|
||||
itemIds.push(stmt.row.id);
|
||||
}
|
||||
else {
|
||||
// This is a real bookmark, so the bookmarked URI is not an orphan.
|
||||
isBookmarked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
return !isBookmarked && tagIds.length > 0 ? tagIds : null;
|
||||
return isBookmarked ? [] : itemIds;
|
||||
},
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
@ -404,20 +432,21 @@ TaggingService.prototype = {
|
||||
onItemRemoved: function TS_onItemRemoved(aItemId, aFolderId, aIndex,
|
||||
aItemType, aURI) {
|
||||
// Item is a tag folder.
|
||||
if (aFolderId == PlacesUtils.tagsFolderId && this._tagFolders[aItemId])
|
||||
if (aFolderId == PlacesUtils.tagsFolderId && this._tagFolders[aItemId]) {
|
||||
delete this._tagFolders[aItemId];
|
||||
|
||||
}
|
||||
// Item is a bookmark that was removed from a non-tag folder.
|
||||
else if (aURI && !this._tagFolders[aFolderId]) {
|
||||
|
||||
// If the only bookmark items now associated with the bookmark's URI are
|
||||
// contained in tag folders, the URI is no longer properly bookmarked, so
|
||||
// untag it.
|
||||
var tagIds = this._getTagsIfUnbookmarkedURI(aURI);
|
||||
if (tagIds)
|
||||
this.untagURI(aURI, tagIds);
|
||||
let itemIds = this._getTaggedItemIdsIfUnbookmarkedURI(aURI);
|
||||
for (let i = 0; i < itemIds.length; i++) {
|
||||
try {
|
||||
PlacesUtils.bookmarks.removeItem(itemIds[i]);
|
||||
} catch (ex) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Item is a tag entry. If this was the last entry for this tag, remove it.
|
||||
else if (aURI && this._tagFolders[aFolderId]) {
|
||||
this._removeTagIfEmpty(aFolderId);
|
||||
|
Loading…
Reference in New Issue
Block a user