Bug 556739 - Part 1: Expose more from PlacesUtils. r=dietrich

This commit is contained in:
Marco Bonardo 2010-04-16 23:51:04 +02:00
parent 6dc8730c40
commit d644ba9c98
13 changed files with 161 additions and 165 deletions

View File

@ -170,7 +170,7 @@ PlacesController.prototype = {
return this._canInsert();
case "placesCmd_new:separator":
return this._canInsert() &&
!asQuery(this._view.getResultNode()).queryOptions.excludeItems &&
!PlacesUtils.asQuery(this._view.getResultNode()).queryOptions.excludeItems &&
this._view.getResult().sortingMode ==
Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
case "placesCmd_show:info":
@ -183,7 +183,7 @@ PlacesController.prototype = {
case "placesCmd_reloadMicrosummary":
var selectedNode = this._view.selectedNode;
return selectedNode && PlacesUtils.nodeIsBookmark(selectedNode) &&
PlacesUIUtils.microsummaries.hasMicrosummary(selectedNode.itemId);
PlacesUtils.microsummaries.hasMicrosummary(selectedNode.itemId);
case "placesCmd_reload":
// Livemark containers
var selectedNode = this._view.selectedNode;
@ -465,7 +465,7 @@ PlacesController.prototype = {
case Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY:
nodeData["query"] = true;
if (node.parent) {
switch (asQuery(node.parent).queryOptions.resultType) {
switch (PlacesUtils.asQuery(node.parent).queryOptions.resultType) {
case Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY:
nodeData["host"] = true;
break;
@ -494,7 +494,7 @@ PlacesController.prototype = {
if (PlacesUtils.nodeIsBookmark(node)) {
nodeData["bookmark"] = true;
PlacesUtils.nodeIsTagQuery(node.parent)
var mss = PlacesUIUtils.microsummaries;
var mss = PlacesUtils.microsummaries;
if (mss.hasMicrosummary(node.itemId))
nodeData["microsummary"] = true;
@ -732,7 +732,7 @@ PlacesController.prototype = {
*/
reloadSelectedMicrosummary: function PC_reloadSelectedMicrosummary() {
var selectedNode = this._view.selectedNode;
var mss = PlacesUIUtils.microsummaries;
var mss = PlacesUtils.microsummaries;
if (mss.hasMicrosummary(selectedNode.itemId))
mss.refreshMicrosummary(selectedNode.itemId);
},
@ -940,7 +940,7 @@ PlacesController.prototype = {
}
else if (PlacesUtils.nodeIsTagQuery(node) && node.parent &&
PlacesUtils.nodeIsQuery(node.parent) &&
asQuery(node.parent).queryOptions.resultType ==
PlacesUtils.asQuery(node.parent).queryOptions.resultType ==
Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY) {
// This is a tag container.
// Untag all URIs tagged with this tag only if the tag container is
@ -953,7 +953,7 @@ PlacesController.prototype = {
}
else if (PlacesUtils.nodeIsURI(node) &&
PlacesUtils.nodeIsQuery(node.parent) &&
asQuery(node.parent).queryOptions.queryType ==
PlacesUtils.asQuery(node.parent).queryOptions.queryType ==
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY) {
// This is a uri node inside an history query.
var bhist = PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory);
@ -962,7 +962,7 @@ PlacesController.prototype = {
}
else if (node.itemId == -1 &&
PlacesUtils.nodeIsQuery(node) &&
asQuery(node).queryOptions.queryType ==
PlacesUtils.asQuery(node).queryOptions.queryType ==
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY) {
// This is a dynamically generated history query, like queries
// grouped by site, time or both. Dynamically generated queries don't
@ -1022,7 +1022,7 @@ PlacesController.prototype = {
}
}
else if (PlacesUtils.nodeIsQuery(node) &&
asQuery(node).queryOptions.queryType ==
PlacesUtils.asQuery(node).queryOptions.queryType ==
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
this._removeHistoryContainer(node);
}
@ -1090,7 +1090,7 @@ PlacesController.prototype = {
if (PlacesUtils.nodeIsFolder(root))
this._removeRowsFromBookmarks(aTxnName);
else if (PlacesUtils.nodeIsQuery(root)) {
var queryType = asQuery(root).queryOptions.queryType;
var queryType = PlacesUtils.asQuery(root).queryOptions.queryType;
if (queryType == Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS)
this._removeRowsFromBookmarks(aTxnName);
else if (queryType == Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)

View File

@ -446,7 +446,7 @@ var gEditItemOverlay = {
if (this._itemId != -1 &&
this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK &&
!this._readOnly)
this._microsummaries = PlacesUIUtils.microsummaries
this._microsummaries = PlacesUtils.microsummaries
.getMicrosummaries(this._uri, -1);
}
catch(ex) {
@ -468,7 +468,7 @@ var gEditItemOverlay = {
var microsummary = enumerator.getNext()
.QueryInterface(Ci.nsIMicrosummary);
var menuItem = this._createMicrosummaryMenuItem(microsummary);
if (PlacesUIUtils.microsummaries
if (PlacesUtils.microsummaries
.isMicrosummary(this._itemId, microsummary))
itemToSelect = menuItem;
@ -693,7 +693,7 @@ var gEditItemOverlay = {
var newTitle = this._element("userEnteredName").label;
if (this._getItemStaticTitle() != newTitle) {
this._mayUpdateFirstEditField("namePicker");
if (PlacesUIUtils.microsummaries.hasMicrosummary(this._itemId)) {
if (PlacesUtils.microsummaries.hasMicrosummary(this._itemId)) {
// Note: this implicitly also takes care of the microsummary->static
// title case, the removeMicorosummary method in the service will set
// the item-title to the value of this annotation.
@ -714,9 +714,9 @@ var gEditItemOverlay = {
// bookmark previously had one, or the user selected a microsummary which
// is not the one the bookmark previously had
if ((newMicrosummary == null &&
PlacesUIUtils.microsummaries.hasMicrosummary(this._itemId)) ||
PlacesUtils.microsummaries.hasMicrosummary(this._itemId)) ||
(newMicrosummary != null &&
!PlacesUIUtils.microsummaries
!PlacesUtils.microsummaries
.isMicrosummary(this._itemId, newMicrosummary))) {
txns.push(ptm.editBookmarkMicrosummary(this._itemId, newMicrosummary));
}
@ -1131,11 +1131,11 @@ var gEditItemOverlay = {
PlacesUtils.annotations.itemHasAnnotation(this._itemId,
LOAD_IN_SIDEBAR_ANNO);
break;
case LMANNO_FEEDURI:
case PlacesUtils.LMANNO_FEEDURI:
var feedURISpec = PlacesUtils.livemarks.getFeedURI(this._itemId).spec;
this._initTextField("feedLocationField", feedURISpec);
break;
case LMANNO_SITEURI:
case PlacesUtils.LMANNO_SITEURI:
var siteURISpec = "";
var siteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
if (siteURI)

View File

@ -981,7 +981,7 @@
// so bail out now and save a lot of work when updating commands
var resultNode = this._resultNode;
if (PlacesUtils.nodeIsQuery(resultNode) &&
asQuery(resultNode).queryOptions.queryType ==
PlacesUtils.asQuery(resultNode).queryOptions.queryType ==
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
return null;

View File

@ -62,7 +62,7 @@ var PlacesOrganizer = {
this._places.selectItems([itemId]);
// Forcefully expand all-bookmarks
if (aQueryName == "AllBookmarks")
asContainer(this._places.selectedNode).containerOpen = true;
PlacesUtils.asContainer(this._places.selectedNode).containerOpen = true;
},
init: function PO_init() {
@ -216,7 +216,7 @@ var PlacesOrganizer = {
return;
var node = this._places.selectedNode;
var queries = asQuery(node).getQueries();
var queries = PlacesUtils.asQuery(node).getQueries();
// Items are only excluded on the left pane.
var options = node.queryOptions.clone();
@ -351,7 +351,7 @@ var PlacesOrganizer = {
* main places pane.
*/
getCurrentOptions: function PO_getCurrentOptions() {
return asQuery(this._content.getResult().root).queryOptions;
return PlacesUtils.asQuery(this._content.getResult().root).queryOptions;
},
/**
@ -359,7 +359,7 @@ var PlacesOrganizer = {
* main places pane.
*/
getCurrentQueries: function PO_getCurrentQueries() {
return asQuery(this._content.getResult().root).getQueries();
return PlacesUtils.asQuery(this._content.getResult().root).getQueries();
},
/**

View File

@ -250,7 +250,7 @@
var popup = document.createElement("menupopup");
popup.setAttribute("placespopup", "true");
button.appendChild(popup);
popup._resultNode = asContainer(aChild);
popup._resultNode = PlacesUtils.asContainer(aChild);
#ifndef XP_MACOSX
popup.setAttribute("context", "placesContext");
#endif

View File

@ -98,7 +98,7 @@
<parameter name="folderRestrict"/>
<body><![CDATA[
// preserve grouping
var queryNode = asQuery(this.getResultNode());
var queryNode = PlacesUtils.asQuery(this.getResultNode());
var options = queryNode.queryOptions.clone();
// Make sure we're getting uri results.
@ -214,7 +214,7 @@
if (childURI == placeURI)
return child;
else if (PlacesUtils.nodeIsContainer(child)) {
var nested = findNode(asContainer(child), placeURI, nodesURIChecked);
var nested = findNode(PlacesUtils.asContainer(child), placeURI, nodesURIChecked);
if (nested)
return nested;
}
@ -442,7 +442,7 @@
// so bail out now and save a lot of work when updating commands
var resultNode = this.getResultNode();
if (PlacesUtils.nodeIsQuery(resultNode) &&
asQuery(resultNode).queryOptions.queryType ==
PlacesUtils.asQuery(resultNode).queryOptions.queryType ==
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
return this._cachedInsertionPoint = null;
@ -535,7 +535,7 @@
if (PlacesControllerDragHelper.disallowInsertion(container))
return null;
var queryOptions = asQuery(result.root).queryOptions;
var queryOptions = PlacesUtils.asQuery(result.root).queryOptions;
if (queryOptions.sortingMode !=
Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) {
// If we are within a sorted view, insert at the end
@ -618,7 +618,7 @@
var index = ids.indexOf(node.itemId);
if (index == -1 &&
node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT)
index = ids.indexOf(asQuery(node).folderItemId);
index = ids.indexOf(PlacesUtils.asQuery(node).folderItemId);
if (index != -1) {
nodes.push(node);
@ -630,7 +630,7 @@
nodesURIChecked.indexOf(node.uri) != -1)
return foundOne;
asContainer(node);
PlacesUtils.asContainer(node);
if (!aOpenContainers && !node.containerOpen)
return foundOne;

View File

@ -653,7 +653,7 @@ PlacesTreeView.prototype = {
this._rows.splice(row, 0, aNode);
this._tree.rowCountChanged(row, 1);
if (PlacesUtils.nodeIsContainer(aNode) && asContainer(aNode).containerOpen)
if (PlacesUtils.nodeIsContainer(aNode) && PlacesUtils.asContainer(aNode).containerOpen)
this.invalidateContainer(aNode);
},
@ -1124,7 +1124,7 @@ PlacesTreeView.prototype = {
if ((PlacesUtils.nodeIsQuery(parent) ||
PlacesUtils.nodeIsFolder(parent)) &&
!node.hasChildren)
return asQuery(parent).queryOptions.expandQueries;
return PlacesUtils.asQuery(parent).queryOptions.expandQueries;
}
return true;
}
@ -1210,7 +1210,7 @@ PlacesTreeView.prototype = {
if (PlacesControllerDragHelper.disallowInsertion(container))
return null;
let queryOptions = asQuery(this._result.root).queryOptions;
let queryOptions = PlacesUtils.asQuery(this._result.root).queryOptions;
if (queryOptions.sortingMode !=
Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) {
// If we are within a sorted view, insert at the end.

View File

@ -57,13 +57,10 @@ __defineGetter__("PlacesUtils", function() {
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
const DESCRIPTION_ANNO = "bookmarkProperties/description";
const GUID_ANNO = "placesInternal/GUID";
const LMANNO_FEEDURI = "livemark/feedURI";
const LMANNO_SITEURI = "livemark/siteURI";
const ORGANIZER_FOLDER_ANNO = "PlacesOrganizer/OrganizerFolder";
const ORGANIZER_QUERY_ANNO = "PlacesOrganizer/OrganizerQuery";
const ORGANIZER_LEFTPANE_VERSION = 6;
const EXCLUDE_FROM_BACKUP_ANNO = "places/excludeFromBackup";
#ifdef XP_MACOSX
// On Mac OSX, the transferable system converts "\r\n" to "\n\n", where we
@ -74,24 +71,7 @@ const NEWLINE= "\n";
const NEWLINE = "\r\n";
#endif
function QI_node(aNode, aIID) {
return aNode.QueryInterface(aIID);
}
function asVisit(aNode) { return QI_node(aNode, Ci.nsINavHistoryVisitResultNode); }
function asFullVisit(aNode){ return QI_node(aNode, Ci.nsINavHistoryFullVisitResultNode);}
function asContainer(aNode){ return QI_node(aNode, Ci.nsINavHistoryContainerResultNode);}
function asQuery(aNode) { return QI_node(aNode, Ci.nsINavHistoryQueryResultNode); }
var PlacesUIUtils = {
/**
* The Microsummary Service
*/
get microsummaries() {
delete this.microsummaries;
return this.microsummaries = Cc["@mozilla.org/microsummary/service;1"].
getService(Ci.nsIMicrosummaryService);
},
get RDF() {
delete this.RDF;
return this.RDF = Cc["@mozilla.org/rdf/rdf-service;1"].
@ -216,7 +196,7 @@ var PlacesUIUtils = {
var keyword = aData.keyword || null;
var annos = aData.annos || [];
// always exclude GUID when copying any item
var excludeAnnos = [GUID_ANNO];
var excludeAnnos = [PlacesUtils.GUID_ANNO];
if (aExcludeAnnotations)
excludeAnnos = excludeAnnos.concat(aExcludeAnnotations);
annos = annos.filter(function(aValue, aIndex, aArray) {
@ -314,7 +294,7 @@ var PlacesUIUtils = {
var annos = aData.annos || [];
annos = annos.filter(function(aAnno) {
// always exclude GUID when copying any item
return aAnno.name != GUID_ANNO;
return aAnno.name != PlacesUtils.GUID_ANNO;
});
return this.ptm.createFolder(aData.title, aContainer, aIndex, annos, childItems);
}
@ -327,16 +307,16 @@ var PlacesUIUtils = {
var feedURI = null;
var siteURI = null;
aData.annos = aData.annos.filter(function(aAnno) {
if (aAnno.name == LMANNO_FEEDURI) {
if (aAnno.name == PlacesUtils.LMANNO_FEEDURI) {
feedURI = PlacesUtils._uri(aAnno.value);
return false;
}
else if (aAnno.name == LMANNO_SITEURI) {
else if (aAnno.name == PlacesUtils.LMANNO_SITEURI) {
siteURI = PlacesUtils._uri(aAnno.value);
return false;
}
// always exclude GUID when copying any item
return aAnno.name != GUID_ANNO;
return aAnno.name != PlacesUtils.GUID_ANNO;
});
return this.ptm.createLivemark(feedURI, siteURI, aData.title, aContainer,
aIndex, aData.annos);
@ -1044,7 +1024,7 @@ var PlacesUIUtils = {
var popup = document.createElement("menupopup");
popup.setAttribute("placespopup", "true");
popup._resultNode = asContainer(aNode);
popup._resultNode = PlacesUtils.asContainer(aNode);
#ifdef XP_MACOSX
// Binding on Mac native menus is lazy attached, so onPopupShowing,
// in the capturing phase, fields are not yet initialized.
@ -1301,7 +1281,7 @@ var PlacesUIUtils = {
as.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, aQueryName,
0, as.EXPIRE_NEVER);
// We should never backup this, since it changes between profiles.
as.setItemAnnotation(itemId, EXCLUDE_FROM_BACKUP_ANNO, 1,
as.setItemAnnotation(itemId, PlacesUtils.EXCLUDE_FROM_BACKUP_ANNO, 1,
0, as.EXPIRE_NEVER);
// Add to the queries map.
self.leftPaneQueries[aQueryName] = itemId;
@ -1315,7 +1295,7 @@ var PlacesUIUtils = {
queries[aFolderName].title,
bs.DEFAULT_INDEX);
// We should never backup this, since it changes between profiles.
as.setItemAnnotation(folderId, EXCLUDE_FROM_BACKUP_ANNO, 1,
as.setItemAnnotation(folderId, PlacesUtils.EXCLUDE_FROM_BACKUP_ANNO, 1,
0, as.EXPIRE_NEVER);
// Disallow manipulating this folder within the organizer UI.
bs.setFolderReadonly(folderId, true);

View File

@ -172,11 +172,11 @@ function test() {
is(shortcutNode.itemId, shortcutId, "shortcut id and shortcut node item id match");
LOG("can move shortcut id?");
dump("can move shortcut id?\n");
is(PlacesControllerDragHelper.canMoveContainer(shortcutId),
true, "should be able to move special folder shortcut id");
LOG("can move shortcut node?");
dump("can move shortcut node?\n");
is(PlacesControllerDragHelper.canMoveNode(shortcutNode),
true, "should be able to move special folder shortcut node");
}

View File

@ -118,12 +118,12 @@ function populate(aFolderId) {
}
function validate(aNode) {
asContainer(aNode);
PlacesUtils.asContainer(aNode);
aNode.containerOpen = true;
is(aNode.childCount, 1, "confirm child count match");
var folderNode = aNode.getChild(0);
is(folderNode.title, "test folder", "confirm folder title");
asContainer(folderNode);
PlacesUtils.asContainer(folderNode);
folderNode.containerOpen = true;
is(folderNode.childCount, 2, "confirm child count match");
var bookmarkNode = folderNode.getChild(0);

View File

@ -57,7 +57,7 @@ function test() {
var testRootId = PlacesUtils.bookmarks.createFolder(toolbarId, "test root", -1);
is(toolbarNode.childCount, oldCount+1, "confirm test root node is a container, and is empty");
var testRootNode = toolbarNode.getChild(toolbarNode.childCount-1);
asContainer(testRootNode);
PlacesUtils.asContainer(testRootNode);
testRootNode.containerOpen = true;
is(testRootNode.childCount, 0, "confirm test root node is a container, and is empty");
@ -120,7 +120,7 @@ function test() {
}
function getGUIDs(aNode) {
asContainer(aNode);
PlacesUtils.asContainer(aNode);
aNode.containerOpen = true;
var GUIDs = {
folder: PlacesUtils.bookmarks.getItemGUID(aNode.itemId),
@ -139,7 +139,7 @@ function checkGUIDs(aFolderNode, aGUIDs, aShouldMatch) {
return aEquals ? (nodeGUID == aGUID) : (nodeGUID != aGUID);
}
asContainer(aFolderNode);
PlacesUtils.asContainer(aFolderNode);
aFolderNode.containerOpen = true;
var allMatch = check(aFolderNode, aGUIDs.folder, aShouldMatch) &&

View File

@ -108,7 +108,7 @@
tree.place = "place:queryType=1&folder=" + leftPaneFolderId;
// Open All Bookmarks
asContainer(tree.view.nodeForTreeIndex(2)).containerOpen = true;
PlacesUtils.asContainer(tree.view.nodeForTreeIndex(2)).containerOpen = true;
// The query-property is set on the title column for each row.
let titleColumn = tree.treeBoxObject.columns.getColumnAt(0);

View File

@ -48,17 +48,17 @@ var Cr = Components.results;
var Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
const EXCLUDE_FROM_BACKUP_ANNO = "places/excludeFromBackup";
const POST_DATA_ANNO = "bookmarkProperties/POSTData";
const READ_ONLY_ANNO = "placesInternal/READ_ONLY";
const LMANNO_FEEDURI = "livemark/feedURI";
const LMANNO_SITEURI = "livemark/siteURI";
const LMANNO_EXPIRATION = "livemark/expiration";
const LMANNO_LOADFAILED = "livemark/loadfailed";
const LMANNO_LOADING = "livemark/loading";
XPCOMUtils.defineLazyGetter(this, "Services", function() {
Cu.import("resource://gre/modules/Services.jsm");
return Services;
});
XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
Cu.import("resource://gre/modules/NetUtil.jsm");
return NetUtil;
});
// The RESTORE_*_NSIOBSERVER_TOPIC constants should match the #defines of the
// same names in browser/components/places/src/nsPlacesImportExportService.cpp
@ -85,10 +85,10 @@ function QI_node(aNode, aIID) {
}
return result;
}
function asVisit(aNode) { return QI_node(aNode, Ci.nsINavHistoryVisitResultNode); }
function asFullVisit(aNode){ return QI_node(aNode, Ci.nsINavHistoryFullVisitResultNode);}
function asContainer(aNode){ return QI_node(aNode, Ci.nsINavHistoryContainerResultNode);}
function asQuery(aNode) { return QI_node(aNode, Ci.nsINavHistoryQueryResultNode); }
function asVisit(aNode) QI_node(aNode, Ci.nsINavHistoryVisitResultNode);
function asFullVisit(aNode) QI_node(aNode, Ci.nsINavHistoryFullVisitResultNode);
function asContainer(aNode) QI_node(aNode, Ci.nsINavHistoryContainerResultNode);
function asQuery(aNode) QI_node(aNode, Ci.nsINavHistoryQueryResultNode);
var PlacesUtils = {
// Place entries that are containers, e.g. bookmark folders or queries.
@ -104,6 +104,21 @@ var PlacesUtils = {
// Place entries as raw URL text
TYPE_UNICODE: "text/unicode",
EXCLUDE_FROM_BACKUP_ANNO: "places/excludeFromBackup",
GUID_ANNO: "placesInternal/GUID",
LMANNO_FEEDURI: "livemark/feedURI",
LMANNO_SITEURI: "livemark/siteURI",
LMANNO_EXPIRATION: "livemark/expiration",
LMANNO_LOADFAILED: "livemark/loadfailed",
LMANNO_LOADING: "livemark/loading",
POST_DATA_ANNO: "bookmarkProperties/POSTData",
READ_ONLY_ANNO: "placesInternal/READ_ONLY",
asVisit: function(aNode) asVisit(aNode),
asFullVisit: function(aNode) asFullVisit(aNode),
asContainer: function(aNode) asContainer(aNode),
asQuery: function(aNode) asQuery(aNode),
/**
* Makes a URI from a spec.
* @param aSpec
@ -224,7 +239,7 @@ var PlacesUtils = {
// observe shutdown, so we can remove the anno observer
Services.obs.addObserver(this, "xpcom-shutdown", false);
var readOnly = this.annotations.getItemsWithAnnotation(READ_ONLY_ANNO);
var readOnly = this.annotations.getItemsWithAnnotation(this.READ_ONLY_ANNO);
this.__defineGetter__("_readOnly", function() readOnly);
return this._readOnly;
},
@ -242,13 +257,13 @@ var PlacesUtils = {
// nsIAnnotationObserver
onItemAnnotationSet: function(aItemId, aAnnotationName) {
if (aAnnotationName == READ_ONLY_ANNO &&
if (aAnnotationName == this.READ_ONLY_ANNO &&
this._readOnly.indexOf(aItemId) == -1)
this._readOnly.push(aItemId);
},
onItemAnnotationRemoved: function(aItemId, aAnnotationName) {
var index = this._readOnly.indexOf(aItemId);
if (aAnnotationName == READ_ONLY_ANNO && index > -1)
if (aAnnotationName == this.READ_ONLY_ANNO && index > -1)
delete this._readOnly[index];
},
onPageAnnotationSet: function(aUri, aAnnotationName) {},
@ -370,7 +385,7 @@ var PlacesUtils = {
// use the annotations service directly to avoid instanciating
// it on startup. (bug 398300)
if (this.__lookupGetter__("livemarks"))
return this.annotations.itemHasAnnotation(aItemId, LMANNO_FEEDURI);
return this.annotations.itemHasAnnotation(aItemId, this.LMANNO_FEEDURI);
// If the livemark service has already been instanciated, use it.
return this.livemarks.isLivemark(aItemId);
},
@ -439,17 +454,16 @@ var PlacesUtils = {
* @returns A string serialization of the node
*/
wrapNode: function PU_wrapNode(aNode, aType, aOverrideURI, aForceCopy) {
let self = this;
// when wrapping a node, we want all the items, even if the original
// query options are excluding them.
// this can happen when copying from the left hand pane of the bookmarks
// organizer
// @return [node, shouldClose]
function convertNode(cNode) {
if (self.nodeIsFolder(cNode) && asQuery(cNode).queryOptions.excludeItems) {
let concreteId = self.getConcreteItemId(cNode);
return [self.getFolderContents(concreteId, false, true).root, true];
if (PlacesUtils.nodeIsFolder(cNode) &&
asQuery(cNode).queryOptions.excludeItems) {
let concreteId = PlacesUtils.getConcreteItemId(cNode);
return [PlacesUtils.getFolderContents(concreteId, false, true).root, true];
}
// If we didn't create our own query, do not alter the node's open state.
@ -468,7 +482,7 @@ var PlacesUtils = {
};
let [node, shouldClose] = convertNode(aNode);
self.serializeNodeAsJSONToOutputStream(node, writer, true, aForceCopy);
this.serializeNodeAsJSONToOutputStream(node, writer, true, aForceCopy);
if (shouldClose)
node.containerOpen = false;
@ -476,11 +490,11 @@ var PlacesUtils = {
}
case this.TYPE_X_MOZ_URL: {
function gatherDataUrl(bNode) {
if (self.nodeIsLivemarkContainer(bNode)) {
let siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
if (PlacesUtils.nodeIsLivemarkContainer(bNode)) {
let siteURI = PlacesUtils.livemarks.getSiteURI(bNode.itemId).spec;
return siteURI + NEWLINE + bNode.title;
}
if (self.nodeIsURI(bNode))
if (PlacesUtils.nodeIsURI(bNode))
return (aOverrideURI || bNode.uri) + NEWLINE + bNode.title;
// ignore containers and separators - items without valid URIs
return "";
@ -505,11 +519,11 @@ var PlacesUtils = {
}
// escape out potential HTML in the title
let escapedTitle = bNode.title ? htmlEscape(bNode.title) : "";
if (self.nodeIsLivemarkContainer(bNode)) {
let siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
if (PlacesUtils.nodeIsLivemarkContainer(bNode)) {
let siteURI = PlacesUtils.livemarks.getSiteURI(bNode.itemId).spec;
return "<A HREF=\"" + siteURI + "\">" + escapedTitle + "</A>" + NEWLINE;
}
if (self.nodeIsContainer(bNode)) {
if (PlacesUtils.nodeIsContainer(bNode)) {
asContainer(bNode);
let wasOpen = bNode.containerOpen;
if (!wasOpen)
@ -526,9 +540,9 @@ var PlacesUtils = {
bNode.containerOpen = wasOpen;
return childString + "</DL>" + NEWLINE;
}
if (self.nodeIsURI(bNode))
if (PlacesUtils.nodeIsURI(bNode))
return "<A HREF=\"" + bNode.uri + "\">" + escapedTitle + "</A>" + NEWLINE;
if (self.nodeIsSeparator(bNode))
if (PlacesUtils.nodeIsSeparator(bNode))
return "<HR>" + NEWLINE;
return "";
}
@ -544,9 +558,9 @@ var PlacesUtils = {
// Otherwise, we wrap as TYPE_UNICODE.
function gatherDataText(bNode) {
if (self.nodeIsLivemarkContainer(bNode))
return self.livemarks.getSiteURI(bNode.itemId).spec;
if (self.nodeIsContainer(bNode)) {
if (PlacesUtils.nodeIsLivemarkContainer(bNode))
return PlacesUtils.livemarks.getSiteURI(bNode.itemId).spec;
if (PlacesUtils.nodeIsContainer(bNode)) {
asContainer(bNode);
let wasOpen = bNode.containerOpen;
if (!wasOpen)
@ -562,9 +576,9 @@ var PlacesUtils = {
bNode.containerOpen = wasOpen;
return childString;
}
if (self.nodeIsURI(bNode))
if (PlacesUtils.nodeIsURI(bNode))
return (aOverrideURI || bNode.uri);
if (self.nodeIsSeparator(bNode))
if (PlacesUtils.nodeIsSeparator(bNode))
return "--------------------";
return "";
}
@ -855,10 +869,10 @@ var PlacesUtils = {
setPostDataForBookmark: function PU_setPostDataForBookmark(aBookmarkId, aPostData) {
const annos = this.annotations;
if (aPostData)
annos.setItemAnnotation(aBookmarkId, POST_DATA_ANNO, aPostData,
annos.setItemAnnotation(aBookmarkId, this.POST_DATA_ANNO, aPostData,
0, Ci.nsIAnnotationService.EXPIRE_NEVER);
else if (annos.itemHasAnnotation(aBookmarkId, POST_DATA_ANNO))
annos.removeItemAnnotation(aBookmarkId, POST_DATA_ANNO);
else if (annos.itemHasAnnotation(aBookmarkId, this.POST_DATA_ANNO))
annos.removeItemAnnotation(aBookmarkId, this.POST_DATA_ANNO);
},
/**
@ -868,8 +882,8 @@ var PlacesUtils = {
*/
getPostDataForBookmark: function PU_getPostDataForBookmark(aBookmarkId) {
const annos = this.annotations;
if (annos.itemHasAnnotation(aBookmarkId, POST_DATA_ANNO))
return annos.getItemAnnotation(aBookmarkId, POST_DATA_ANNO);
if (annos.itemHasAnnotation(aBookmarkId, this.POST_DATA_ANNO))
return annos.getItemAnnotation(aBookmarkId, this.POST_DATA_ANNO);
return null;
},
@ -966,9 +980,9 @@ var PlacesUtils = {
if (this.__lookupGetter__("livemarks")) {
var feedSpec = aFeedURI.spec
var annosvc = this.annotations;
var livemarks = annosvc.getItemsWithAnnotation(LMANNO_FEEDURI);
var livemarks = annosvc.getItemsWithAnnotation(this.LMANNO_FEEDURI);
for (var i = 0; i < livemarks.length; i++) {
if (annosvc.getItemAnnotation(livemarks[i], LMANNO_FEEDURI) == feedSpec)
if (annosvc.getItemAnnotation(livemarks[i], this.LMANNO_FEEDURI) == feedSpec)
return livemarks[i];
}
}
@ -1126,38 +1140,38 @@ var PlacesUtils = {
});
var batch = {
_utils: this,
nodes: nodes[0].children,
runBatched: function restore_runBatched() {
if (aReplace) {
// Get roots excluded from the backup, we will not remove them
// before restoring.
var excludeItems = this._utils.annotations
.getItemsWithAnnotation(EXCLUDE_FROM_BACKUP_ANNO);
var excludeItems = PlacesUtils.annotations.getItemsWithAnnotation(
PlacesUtils.EXCLUDE_FROM_BACKUP_ANNO
);
// delete existing children of the root node, excepting:
// 1. special folders: delete the child nodes
// 2. tags folder: untag via the tagging api
var query = this._utils.history.getNewQuery();
query.setFolders([this._utils.placesRootId], 1);
var options = this._utils.history.getNewQueryOptions();
var query = PlacesUtils.history.getNewQuery();
query.setFolders([PlacesUtils.placesRootId], 1);
var options = PlacesUtils.history.getNewQueryOptions();
options.expandQueries = false;
var root = this._utils.history.executeQuery(query, options).root;
var root = PlacesUtils.history.executeQuery(query, options).root;
root.containerOpen = true;
var childIds = [];
for (var i = 0; i < root.childCount; i++) {
var childId = root.getChild(i).itemId;
if (excludeItems.indexOf(childId) == -1 &&
childId != this._utils.tagsFolderId)
childId != PlacesUtils.tagsFolderId)
childIds.push(childId);
}
root.containerOpen = false;
for (var i = 0; i < childIds.length; i++) {
var rootItemId = childIds[i];
if (this._utils.isRootItem(rootItemId))
this._utils.bookmarks.removeFolderChildren(rootItemId);
if (PlacesUtils.isRootItem(rootItemId))
PlacesUtils.bookmarks.removeFolderChildren(rootItemId);
else
this._utils.bookmarks.removeItem(rootItemId);
PlacesUtils.bookmarks.removeItem(rootItemId);
}
}
@ -1199,7 +1213,7 @@ var PlacesUtils = {
else
this.importJSONNode(node, this.placesRootId, node.index);
}, this._utils);
}, PlacesUtils);
// fixup imported place: uris that contain folders
searchIds.forEach(function(aId) {
@ -1208,7 +1222,7 @@ var PlacesUtils = {
folderIdMap);
if (!uri.equals(oldURI))
this.bookmarks.changeBookmarkURI(aId, uri);
}, this._utils);
}, PlacesUtils);
}
};
@ -1253,15 +1267,15 @@ var PlacesUtils = {
var siteURI = null;
aData.annos = aData.annos.filter(function(aAnno) {
switch (aAnno.name) {
case LMANNO_FEEDURI:
case this.LMANNO_FEEDURI:
feedURI = this._uri(aAnno.value);
return false;
case LMANNO_SITEURI:
case this.LMANNO_SITEURI:
siteURI = this._uri(aAnno.value);
return false;
case LMANNO_EXPIRATION:
case LMANNO_LOADING:
case LMANNO_LOADFAILED:
case this.LMANNO_EXPIRATION:
case this.LMANNO_LOADING:
case this.LMANNO_LOADFAILED:
return false;
default:
return true;
@ -1386,8 +1400,6 @@ var PlacesUtils = {
function PU_serializeNodeAsJSONToOutputStream(aNode, aStream, aIsUICommand,
aResolveShortcuts,
aExcludeItems) {
var self = this;
function addGenericProperties(aPlacesNode, aJSNode) {
aJSNode.title = aPlacesNode.title;
aJSNode.id = aPlacesNode.itemId;
@ -1405,14 +1417,14 @@ var PlacesUtils = {
// XXX need a hasAnnos api
var annos = [];
try {
annos = self.getAnnotationsForItem(aJSNode.id).filter(function(anno) {
annos = PlacesUtils.getAnnotationsForItem(aJSNode.id).filter(function(anno) {
// XXX should whitelist this instead, w/ a pref for
// backup/restore of non-whitelisted annos
// XXX causes JSON encoding errors, so utf-8 encode
//anno.value = unescape(encodeURIComponent(anno.value));
if (anno.name == LMANNO_FEEDURI)
if (anno.name == PlacesUtils.LMANNO_FEEDURI)
aJSNode.livemark = 1;
if (anno.name == READ_ONLY_ANNO && aResolveShortcuts) {
if (anno.name == PlacesUtils.READ_ONLY_ANNO && aResolveShortcuts) {
// When copying a read-only node, remove the read-only annotation.
return false;
}
@ -1426,11 +1438,11 @@ var PlacesUtils = {
}
function addURIProperties(aPlacesNode, aJSNode) {
aJSNode.type = self.TYPE_X_MOZ_PLACE;
aJSNode.type = PlacesUtils.TYPE_X_MOZ_PLACE;
aJSNode.uri = aPlacesNode.uri;
if (aJSNode.id && aJSNode.id != -1) {
// harvest bookmark-specific properties
var keyword = self.bookmarks.getKeywordForBookmark(aJSNode.id);
var keyword = PlacesUtils.bookmarks.getKeywordForBookmark(aJSNode.id);
if (keyword)
aJSNode.keyword = keyword;
}
@ -1440,14 +1452,14 @@ var PlacesUtils = {
aJSNode.tags = tags;
// last character-set
var uri = self._uri(aPlacesNode.uri);
var lastCharset = self.history.getCharsetForURI(uri);
var uri = PlacesUtils._uri(aPlacesNode.uri);
var lastCharset = PlacesUtils.history.getCharsetForURI(uri);
if (lastCharset)
aJSNode.charset = lastCharset;
}
function addSeparatorProperties(aPlacesNode, aJSNode) {
aJSNode.type = self.TYPE_X_MOZ_PLACE_SEPARATOR;
aJSNode.type = PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR;
}
function addContainerProperties(aPlacesNode, aJSNode) {
@ -1456,38 +1468,38 @@ var PlacesUtils = {
// This is a bookmark or a tag container.
if (PlacesUtils.nodeIsQuery(aPlacesNode) ||
(concreteId != aPlacesNode.itemId && !aResolveShortcuts)) {
aJSNode.type = self.TYPE_X_MOZ_PLACE;
aJSNode.type = PlacesUtils.TYPE_X_MOZ_PLACE;
aJSNode.uri = aPlacesNode.uri;
// folder shortcut
if (aIsUICommand)
aJSNode.concreteId = concreteId;
}
else { // Bookmark folder or a shortcut we should convert to folder.
aJSNode.type = self.TYPE_X_MOZ_PLACE_CONTAINER;
aJSNode.type = PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER;
// Mark root folders.
if (aJSNode.id == self.placesRootId)
if (aJSNode.id == PlacesUtils.placesRootId)
aJSNode.root = "placesRoot";
else if (aJSNode.id == self.bookmarksMenuFolderId)
else if (aJSNode.id == PlacesUtils.bookmarksMenuFolderId)
aJSNode.root = "bookmarksMenuFolder";
else if (aJSNode.id == self.tagsFolderId)
else if (aJSNode.id == PlacesUtils.tagsFolderId)
aJSNode.root = "tagsFolder";
else if (aJSNode.id == self.unfiledBookmarksFolderId)
else if (aJSNode.id == PlacesUtils.unfiledBookmarksFolderId)
aJSNode.root = "unfiledBookmarksFolder";
else if (aJSNode.id == self.toolbarFolderId)
else if (aJSNode.id == PlacesUtils.toolbarFolderId)
aJSNode.root = "toolbarFolder";
}
}
else {
// This is a grouped container query, generated on the fly.
aJSNode.type = self.TYPE_X_MOZ_PLACE;
aJSNode.type = PlacesUtils.TYPE_X_MOZ_PLACE;
aJSNode.uri = aPlacesNode.uri;
}
}
function writeScalarNode(aStream, aNode) {
// serialize to json
var jstr = self.toJSONString(aNode);
var jstr = PlacesUtils.toJSONString(aNode);
// write to stream
aStream.write(jstr, jstr.length);
}
@ -1498,7 +1510,7 @@ var PlacesUtils = {
var properties = [];
for (let [name, value] in Iterator(aNode)) {
if (name == "annos")
value = self.toJSONString(value);
value = PlacesUtils.toJSONString(value);
else if (typeof value == "string")
value = "\"" + value.replace(escJSONStringRegExp, '\\$1') + "\"";
properties.push("\"" + name.replace(escJSONStringRegExp, '\\$1') + "\":" + value);
@ -1543,37 +1555,37 @@ var PlacesUtils = {
var parent = bNode.parent;
var grandParent = parent ? parent.parent : null;
if (self.nodeIsURI(bNode)) {
if (PlacesUtils.nodeIsURI(bNode)) {
// Tag root accept only folder nodes
if (parent && parent.itemId == self.tagsFolderId)
if (parent && parent.itemId == PlacesUtils.tagsFolderId)
return false;
// Check for url validity, since we can't halt while writing a backup.
// This will throw if we try to serialize an invalid url and it does
// not make sense saving a wrong or corrupt uri node.
try {
self._uri(bNode.uri);
PlacesUtils._uri(bNode.uri);
} catch (ex) {
return false;
}
addURIProperties(bNode, node);
}
else if (self.nodeIsContainer(bNode)) {
else if (PlacesUtils.nodeIsContainer(bNode)) {
// Tag containers accept only uri nodes
if (grandParent && grandParent.itemId == self.tagsFolderId)
if (grandParent && grandParent.itemId == PlacesUtils.tagsFolderId)
return false;
addContainerProperties(bNode, node);
}
else if (self.nodeIsSeparator(bNode)) {
else if (PlacesUtils.nodeIsSeparator(bNode)) {
// Tag root accept only folder nodes
// Tag containers accept only uri nodes
if ((parent && parent.itemId == self.tagsFolderId) ||
(grandParent && grandParent.itemId == self.tagsFolderId))
if ((parent && parent.itemId == PlacesUtils.tagsFolderId) ||
(grandParent && grandParent.itemId == PlacesUtils.tagsFolderId))
return false;
addSeparatorProperties(bNode, node);
}
if (!node.feedURI && node.type == self.TYPE_X_MOZ_PLACE_CONTAINER)
if (!node.feedURI && node.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER)
writeComplexNode(aStream, node, bNode);
else
writeScalarNode(aStream, node);
@ -1845,7 +1857,7 @@ var PlacesUtils = {
// Get list of itemIds that must be exluded from the backup.
let excludeItems =
PlacesUtils.annotations.getItemsWithAnnotation(EXCLUDE_FROM_BACKUP_ANNO);
PlacesUtils.annotations.getItemsWithAnnotation(PlacesUtils.EXCLUDE_FROM_BACKUP_ANNO);
// Query the Places root.
let options = PlacesUtils.history.getNewQueryOptions();
@ -1970,6 +1982,10 @@ XPCOMUtils.defineLazyServiceGetter(PlacesUtils, "livemarks",
"@mozilla.org/browser/livemark-service;2",
"nsILivemarkService");
XPCOMUtils.defineLazyServiceGetter(PlacesUtils, "microsummaries",
"@mozilla.org/microsummary/service;1",
"nsIMicrosummaryService");
XPCOMUtils.defineLazyGetter(PlacesUtils, "_bundle", function() {
const PLACES_STRING_BUNDLE_URI = "chrome://places/locale/places.properties";
return Cc["@mozilla.org/intl/stringbundle;1"].