diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index fd20e799de4..9ff9672a823 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -320,9 +320,10 @@ pref("browser.tabs.selectOwnerOnClose", true); pref("browser.bookmarks.sort.direction", "descending"); pref("browser.bookmarks.sort.resource", "rdf:http://home.netscape.com/NC-rdf#Name"); -// By default, do not overwrite bookmarks.html in the profile directory -// See bug #381216 for details -pref("browser.bookmarks.overwrite", false); +// By default, do not export HTML at shutdown. +// If true, at shutdown the bookmarks in your menu and toolbar will +// be exported as HTML to the bookmarks.html file. +pref("browser.bookmarks.autoExportHTML", false); // Scripts & Windows prefs pref("dom.disable_open_during_load", true); diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc index b15fd204d05..e63a9759985 100644 --- a/browser/base/content/browser-menubar.inc +++ b/browser/base/content/browser-menubar.inc @@ -329,7 +329,7 @@ diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js index 28c589c15b5..fa1ea3c6261 100644 --- a/browser/base/content/browser-places.js +++ b/browser/base/content/browser-places.js @@ -105,7 +105,7 @@ var StarUI = { this._itemId = -1; this._uri = null; if (this._batching) { - PlacesUtils.ptm.endBatch(); + PlacesUIUtils.ptm.endBatch(); this._batching = false; } } @@ -188,11 +188,11 @@ var StarUI = { // Otherwise, if no changes were done in the edit-item panel, the last // transaction on the undo stack may be the initial createItem transaction, // or worse, the batched editing of some other item. - PlacesUtils.ptm.doTransaction({ doTransaction: function() { }, - undoTransaction: function() { }, - redoTransaction: function() { }, - isTransient: false, - merge: function() { return false; } }); + PlacesUIUtils.ptm.doTransaction({ doTransaction: function() { }, + undoTransaction: function() { }, + redoTransaction: function() { }, + isTransient: false, + merge: function() { return false; } }); if (this.panel.state == "closed") { // Consume dismiss clicks, see bug 400924 @@ -271,7 +271,7 @@ var StarUI = { cancelButtonOnCommand: function SU_cancelButtonOnCommand() { this.endBatch(); - PlacesUtils.ptm.undoTransaction(); + PlacesUIUtils.ptm.undoTransaction(); this.panel.hidePopup(); }, @@ -282,8 +282,8 @@ var StarUI = { // a "Bookmark Removed" notification along with an Undo button is // shown if (this._batching) { - PlacesUtils.ptm.endBatch(); - PlacesUtils.ptm.beginBatch(); // allow undo from within the notification + PlacesUIUtils.ptm.endBatch(); + PlacesUIUtils.ptm.beginBatch(); // allow undo from within the notification var bundle = this._element("bundle_browser"); // "Bookmark Removed" title (the description field is already empty in @@ -308,8 +308,8 @@ var StarUI = { // the tags for the url var itemIds = PlacesUtils.getBookmarksForURI(this._uri); for (var i=0; i < itemIds.length; i++) { - var txn = PlacesUtils.ptm.removeItem(itemIds[i]); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.removeItem(itemIds[i]); + PlacesUIUtils.ptm.doTransaction(txn); } #ifdef ADVANCED_STARRING_UI @@ -324,21 +324,21 @@ var StarUI = { // restore the bookmark by undoing the last transaction and go back // to the edit state this.endBatch(); - PlacesUtils.ptm.undoTransaction(); + PlacesUIUtils.ptm.undoTransaction(); this._itemId = PlacesUtils.getMostRecentBookmarkForURI(this._uri); this.showEditBookmarkPopup(); }, beginBatch: function SU_beginBatch() { if (!this._batching) { - PlacesUtils.ptm.beginBatch(); + PlacesUIUtils.ptm.beginBatch(); this._batching = true; } }, endBatch: function SU_endBatch() { if (this._batching) { - PlacesUtils.ptm.endBatch(); + PlacesUIUtils.ptm.endBatch(); this._batching = false; } } @@ -372,7 +372,7 @@ var PlacesCommandHook = { var description; try { title = webNav.document.title || url.spec; - description = PlacesUtils.getDescriptionFromDocument(webNav.document); + description = PlacesUIUtils.getDescriptionFromDocument(webNav.document); } catch (e) { } @@ -386,9 +386,9 @@ var PlacesCommandHook = { var parent = aParent != undefined ? aParent : PlacesUtils.unfiledBookmarksFolderId; var descAnno = { name: DESCRIPTION_ANNO, value: description }; - var txn = PlacesUtils.ptm.createItem(uri, parent, -1, - title, null, [descAnno]); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.createItem(uri, parent, -1, + title, null, [descAnno]); + PlacesUIUtils.ptm.doTransaction(txn); itemId = PlacesUtils.getMostRecentBookmarkForURI(uri); } @@ -432,8 +432,8 @@ var PlacesCommandHook = { var itemId = PlacesUtils.getMostRecentBookmarkForURI(linkURI); if (itemId == -1) { StarUI.beginBatch(); - var txn = PlacesUtils.ptm.createItem(linkURI, aParent, -1, aTitle); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.createItem(linkURI, aParent, -1, aTitle); + PlacesUIUtils.ptm.doTransaction(txn); itemId = PlacesUtils.getMostRecentBookmarkForURI(linkURI); } @@ -474,7 +474,7 @@ var PlacesCommandHook = { */ bookmarkCurrentPages: function PCH_bookmarkCurrentPages() { var tabURIs = this._getUniqueTabInfo(); - PlacesUtils.showMinimalAddMultiBookmarkUI(tabURIs); + PlacesUIUtils.showMinimalAddMultiBookmarkUI(tabURIs); }, @@ -500,12 +500,12 @@ var PlacesCommandHook = { if (arguments.length > 2) description = feedSubtitle; else - description = PlacesUtils.getDescriptionFromDocument(doc); + description = PlacesUIUtils.getDescriptionFromDocument(doc); var toolbarIP = new InsertionPoint(PlacesUtils.bookmarks.toolbarFolder, -1); - PlacesUtils.showMinimalAddLivemarkUI(feedURI, gBrowser.currentURI, - title, description, toolbarIP, true); + PlacesUIUtils.showMinimalAddLivemarkUI(feedURI, gBrowser.currentURI, + title, description, toolbarIP, true); }, /** @@ -581,7 +581,7 @@ var BookmarksEventHandler = { return; var target = aEvent.originalTarget; - var view = PlacesUtils.getViewForNode(target); + var view = PlacesUIUtils.getViewForNode(target); if (target.node && PlacesUtils.nodeIsFolder(target.node)) { // Don't open the root folder in tabs when the empty area on the toolbar // is middle-clicked or when a non-bookmark item except for Open in Tabs) @@ -625,7 +625,7 @@ var BookmarksEventHandler = { onCommand: function BM_onCommand(aEvent) { var target = aEvent.originalTarget; if (target.node) - PlacesUtils.openNodeWithEvent(target.node, aEvent); + PlacesUIUtils.openNodeWithEvent(target.node, aEvent); }, /** @@ -685,7 +685,7 @@ var BookmarksEventHandler = { openHomePage.setAttribute("onclick", "checkForMiddleClick(this, event); event.stopPropagation();"); openHomePage.setAttribute("label", - PlacesUtils.getFormattedString("menuOpenLivemarkOrigin.label", + PlacesUIUtils.getFormattedString("menuOpenLivemarkOrigin.label", [target.parentNode.getAttribute("label")])); target.appendChild(openHomePage); } @@ -694,7 +694,7 @@ var BookmarksEventHandler = { var openInTabs = document.createElement("menuitem"); openInTabs.setAttribute("openInTabs", "true"); openInTabs.setAttribute("oncommand", - "PlacesUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);"); + "PlacesUIUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);"); openInTabs.setAttribute("label", gNavigatorBundle.getString("menuOpenAllInTabs.label")); target.appendChild(openInTabs); @@ -755,7 +755,7 @@ var BookmarksMenuDropHandler = { getSupportedFlavours: function BMDH_getSupportedFlavours() { var flavorSet = new FlavourSet(); var view = document.getElementById("bookmarksMenuPopup"); - var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES + var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES for (var i = 0; i < types.length; ++i) flavorSet.appendFlavour(types[i]); return flavorSet; diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index d0c1b3be9ee..7b81f4039bb 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -2549,7 +2549,7 @@ var bookmarksButtonObserver = { var split = aXferData.data.split("\n"); var url = split[0]; if (url != aXferData.data) // do nothing if it's not a valid URL - PlacesUtils.showMinimalAddBookmarkUI(makeURI(url), split[1]); + PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(url), split[1]); }, onDragOver: function (aEvent, aFlavour, aDragSession) @@ -3019,7 +3019,7 @@ function addToUrlbarHistory(aUrlToAdd) try { if (aUrlToAdd.indexOf(" ") == -1) { - PlacesUtils.markPageAsTyped(aUrlToAdd); + PlacesUIUtils.markPageAsTyped(aUrlToAdd); } } catch(ex) { @@ -4430,9 +4430,9 @@ function asyncOpenWebPanel(event) // This is the Opera convention for a special link that - when clicked - allows // you to add a sidebar panel. We support the Opera convention here. The link's // title attribute contains the title that should be used for the sidebar panel. - PlacesUtils.showMinimalAddBookmarkUI(makeURI(wrapper.href), - wrapper.getAttribute("title"), - null, null, true, true); + PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(wrapper.href), + wrapper.getAttribute("title"), + null, null, true, true); event.preventDefault(); return false; } @@ -5396,9 +5396,9 @@ function AddKeywordForSearchField() else spec += "?" + formData.join("&"); - var description = PlacesUtils.getDescriptionFromDocument(node.ownerDocument); - PlacesUtils.showMinimalAddBookmarkUI(makeURI(spec), "", description, null, - null, null, "", postData); + var description = PlacesUIUtils.getDescriptionFromDocument(node.ownerDocument); + PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(spec), "", description, null, + null, null, "", postData); } function SwitchDocumentDirection(aWindow) { diff --git a/browser/base/content/nsContextMenu.js b/browser/base/content/nsContextMenu.js index bd82882c613..b08b46fdc58 100644 --- a/browser/base/content/nsContextMenu.js +++ b/browser/base/content/nsContextMenu.js @@ -1191,13 +1191,13 @@ nsContextMenu.prototype = { var itemId = PlacesUtils.getMostRecentBookmarkForURI(uri); if (itemId == -1) { var title = doc.title; - var description = PlacesUtils.getDescriptionFromDocument(doc); + var description = PlacesUIUtils.getDescriptionFromDocument(doc); var descAnno = { name: DESCRIPTION_ANNO, value: description }; - var txn = PlacesUtils.ptm.createItem(uri, + var txn = PlacesUIUtils.ptm.createItem(uri, PlacesUtils.bookmarksMenuFolderId, -1, title, null, [descAnno]); - PlacesUtils.ptm.doTransaction(txn); + PlacesUIUtils.ptm.doTransaction(txn); itemId = PlacesUtils.getMostRecentBookmarkForURI(uri); StarUI.beginBatch(); } diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 8e969d236b7..0089fd263e8 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -45,6 +45,13 @@ const Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource:///modules/distribution.js"); +// Check to see if bookmarks need backing up once per +// day on 1 hour idle. +const BOOKMARKS_ARCHIVE_IDLE_TIME = 60 * 60; + +// Backup bookmarks once every 24 hours. +const BOOKMARKS_ARCHIVE_INTERVAL = 86400 * 1000; + // Factory object const BrowserGlueServiceFactory = { _instance: null, @@ -103,15 +110,23 @@ BrowserGlue.prototype = { if (this._saveSession) { this._setPrefToSaveSession(); } + this._shutdownPlaces(); + this.idleService.removeIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME); break; case "session-save": this._setPrefToSaveSession(); subject.QueryInterface(Ci.nsISupportsPRBool); subject.data = true; break; + case "idle": + if (this.idleService.idleTime > BOOKMARKS_ARCHIVE_IDLE_TIME * 1000) { + // Back up bookmarks. + this._archiveBookmarks(); + } + break; } - } -, + }, + // initialization (called on application startup) _init: function() { @@ -324,6 +339,14 @@ BrowserGlue.prototype = { return Sanitizer; }, + _idleService: null, + get idleService() { + if (!this._idleService) + this._idleService = Cc["@mozilla.org/widget/idleservice;1"]. + getService(Ci.nsIIdleService); + return this._idleService; + }, + /** * Initialize Places * - imports the bookmarks html file if bookmarks datastore is empty @@ -336,10 +359,11 @@ BrowserGlue.prototype = { var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"]. getService(Ci.nsINavHistoryService); + var prefBranch = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefBranch); + var importBookmarks = false; try { - var prefBranch = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefBranch); importBookmarks = prefBranch.getBoolPref("browser.places.importBookmarksHTML"); } catch(ex) {} @@ -355,46 +379,39 @@ BrowserGlue.prototype = { // Call it here for Fx3 profiles created before the Places folder // has been added, otherwise it's called during import. this.ensurePlacesDefaultQueriesInitialized(); - return; } + else { + // ensurePlacesDefaultQueriesInitialized() is called by import. + prefBranch.setBoolPref("browser.places.createdSmartBookmarks", false); - // ensurePlacesDefaultQueriesInitialized() is called by import. - prefBranch.setBoolPref("browser.places.createdSmartBookmarks", false); + // get latest backup + Cu.import("resource://gre/modules/utils.js"); + var bookmarksFile = PlacesUtils.getMostRecentBackup(); - var dirService = Cc["@mozilla.org/file/directory_service;1"]. - getService(Ci.nsIProperties); - - var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile); - - if (bookmarksFile.exists()) { - // import the file - try { - var importer = - Cc["@mozilla.org/browser/places/import-export-service;1"]. - getService(Ci.nsIPlacesImportExportService); - importer.importHTMLFromFile(bookmarksFile, true); - } catch(ex) { - } finally { - prefBranch.setBoolPref("browser.places.importBookmarksHTML", false); + if (bookmarksFile.leafName.match("\.json$")) { + // restore a JSON backup + PlacesUtils.restoreBookmarksFromJSONFile(bookmarksFile); } + else { + // if there's no json backup use bookmarks.html + var dirService = Cc["@mozilla.org/file/directory_service;1"]. + getService(Ci.nsIProperties); + var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile); - // only back up pre-places bookmarks.html if we plan on overwriting it - if (prefBranch.getBoolPref("browser.bookmarks.overwrite")) { - // backup pre-places bookmarks.html - // XXXtodo remove this before betas, after import/export is solid - var profDir = dirService.get("ProfD", Ci.nsILocalFile); - var bookmarksBackup = profDir.clone(); - bookmarksBackup.append("bookmarks.preplaces.html"); - if (!bookmarksBackup.exists()) { - // save old bookmarks.html file as bookmarks.preplaces.html - try { - bookmarksFile.copyTo(profDir, "bookmarks.preplaces.html"); - } catch(ex) { - dump("nsBrowserGlue::_initPlaces(): copy of bookmarks.html to bookmarks.preplaces.html failed: " + ex + "\n"); - } + // import the file + try { + var importer = Cc["@mozilla.org/browser/places/import-export-service;1"]. + getService(Ci.nsIPlacesImportExportService); + importer.importHTMLFromFile(bookmarksFile, true /* overwrite existing */); + } finally { + prefBranch.setBoolPref("browser.places.importBookmarksHTML", false); } } } + + // Initialize bookmark archiving on idle. + // Once a day, either on idle or shutdown, bookmarks are backed up. + this.idleService.addIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME); }, /** diff --git a/browser/components/places/content/bookmarkProperties.js b/browser/components/places/content/bookmarkProperties.js index a1dd76f4f4c..540d67e4c68 100755 --- a/browser/components/places/content/bookmarkProperties.js +++ b/browser/components/places/content/bookmarkProperties.js @@ -567,8 +567,8 @@ var BookmarkPropertiesPanel = { var itemToSelect = userEnteredNameField; try { this._microsummaries = - PlacesUtils.microsummaries.getMicrosummaries(this._bookmarkURI, - this._bookmarkId); + PlacesUIUtils.microsummaries.getMicrosummaries(this._bookmarkURI, + this._bookmarkId); } catch(ex) { // getMicrosummaries will throw an exception if the page to which the URI @@ -590,8 +590,8 @@ var BookmarkPropertiesPanel = { var menuItem = this._createMicrosummaryMenuItem(microsummary); if (this._action == ACTION_EDIT && - PlacesUtils.microsummaries - .isMicrosummary(this._bookmarkId, microsummary)) + PlacesUIUtils.microsummaries + .isMicrosummary(this._bookmarkId, microsummary)) itemToSelect = menuItem; menupopup.appendChild(menuItem); @@ -713,7 +713,7 @@ var BookmarkPropertiesPanel = { try { var value = this._element(aTextboxID).value; if (value) { - var uri = PlacesUtils.createFixedURI(value); + var uri = PlacesUIUtils.createFixedURI(value); return true; } } catch (e) { } @@ -725,7 +725,7 @@ var BookmarkPropertiesPanel = { */ _getEditTitleTransaction: function BPP__getEditTitleTransaction(aItemId, aNewTitle) { - return PlacesUtils.ptm.editItemTitle(aItemId, aNewTitle); + return PlacesUIUtils.ptm.editItemTitle(aItemId, aNewTitle); }, /** @@ -813,21 +813,21 @@ var BookmarkPropertiesPanel = { // description var description = this._element("descriptionTextfield").value; if (description != this._itemDescription) { - transactions.push(PlacesUtils.ptm. + transactions.push(PlacesUIUtils.ptm. editItemDescription(itemId, description, this._itemType != BOOKMARK_ITEM)); } if (this._itemType == BOOKMARK_ITEM) { // location - var url = PlacesUtils.createFixedURI(this._element("editURLBar").value); + var url = PlacesUIUtils.createFixedURI(this._element("editURLBar").value); if (!this._bookmarkURI.equals(url)) - transactions.push(PlacesUtils.ptm.editBookmarkURI(itemId, url)); + transactions.push(PlacesUIUtils.ptm.editBookmarkURI(itemId, url)); // keyword transactions var newKeyword = this._element("keywordTextfield").value; if (newKeyword != this._bookmarkKeyword) { - transactions.push(PlacesUtils.ptm. + transactions.push(PlacesUIUtils.ptm. editBookmarkKeyword(itemId, newKeyword)); } @@ -841,39 +841,39 @@ var BookmarkPropertiesPanel = { // selected a microsummary which is not the one the bookmark previously // had. if ((newMicrosummary == null && - PlacesUtils.microsummaries.hasMicrosummary(itemId)) || + PlacesUIUtils.microsummaries.hasMicrosummary(itemId)) || (newMicrosummary != null && - !PlacesUtils.microsummaries - .isMicrosummary(itemId, newMicrosummary))) { + !PlacesUIUtils.microsummaries + .isMicrosummary(itemId, newMicrosummary))) { transactions.push( - PlacesUtils.ptm.editBookmarkMicrosummary(itemId, newMicrosummary)); + PlacesUIUtils.ptm.editBookmarkMicrosummary(itemId, newMicrosummary)); } // load in sidebar var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked; if (loadInSidebarChecked != this._loadBookmarkInSidebar) { transactions.push( - PlacesUtils.ptm.setLoadInSidebar(itemId, loadInSidebarChecked)); + PlacesUIUtils.ptm.setLoadInSidebar(itemId, loadInSidebarChecked)); } } else if (this._itemType == LIVEMARK_CONTAINER) { var feedURIString = this._element("feedLocationTextfield").value; - var feedURI = PlacesUtils.createFixedURI(feedURIString); + var feedURI = PlacesUIUtils.createFixedURI(feedURIString); if (!this._feedURI.equals(feedURI)) { transactions.push( - PlacesUtils.ptm.editLivemarkFeedURI(this._folderId, feedURI)); + PlacesUIUtils.ptm.editLivemarkFeedURI(this._folderId, feedURI)); } // Site Location is empty, we can set its URI to null var newSiteURIString = this._element("feedSiteLocationTextfield").value; var newSiteURI = null; if (newSiteURIString) - newSiteURI = PlacesUtils.createFixedURI(newSiteURIString); + newSiteURI = PlacesUIUtils.createFixedURI(newSiteURIString); if ((!newSiteURI && this._siteURI) || (newSiteURI && (!this._siteURI || !this._siteURI.equals(newSiteURI)))) { transactions.push( - PlacesUtils.ptm.editLivemarkSiteURI(this._folderId, newSiteURI)); + PlacesUIUtils.ptm.editLivemarkSiteURI(this._folderId, newSiteURI)); } } @@ -882,8 +882,8 @@ var BookmarkPropertiesPanel = { if (transactions.length > 0) { window.arguments[0].performed = true; var aggregate = - PlacesUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions); - PlacesUtils.ptm.doTransaction(aggregate); + PlacesUIUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions); + PlacesUIUtils.ptm.doTransaction(aggregate); } }, @@ -912,7 +912,7 @@ var BookmarkPropertiesPanel = { */ _getCreateNewBookmarkTransaction: function BPP__getCreateNewBookmarkTransaction(aContainer, aIndex) { - var uri = PlacesUtils.createFixedURI(this._element("editURLBar").value); + var uri = PlacesUIUtils.createFixedURI(this._element("editURLBar").value); var title = this._element("userEnteredName").label; var keyword = this._element("keywordTextfield").value; var annotations = []; @@ -928,20 +928,20 @@ var BookmarkPropertiesPanel = { var microsummary = this._element("namePicker").selectedItem.microsummary; if (microsummary) { childTransactions.push( - PlacesUtils.ptm.editBookmarkMicrosummary(-1, microsummary)); + PlacesUIUtils.ptm.editBookmarkMicrosummary(-1, microsummary)); } if (this._postData) { childTransactions.push( - PlacesUtils.ptm.editBookmarkPostData(-1, this._postData)); + PlacesUIUtils.ptm.editBookmarkPostData(-1, this._postData)); } - var transactions = [PlacesUtils.ptm.createItem(uri, aContainer, aIndex, - title, keyword, - annotations, - childTransactions)]; + var transactions = [PlacesUIUtils.ptm.createItem(uri, aContainer, aIndex, + title, keyword, + annotations, + childTransactions)]; - return PlacesUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions); + return PlacesUIUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions); }, /** @@ -953,7 +953,7 @@ var BookmarkPropertiesPanel = { for (var i = 0; i < this._URIList.length; ++i) { var uri = this._URIList[i]; var title = this._getURITitleFromHistory(uri); - transactions.push(PlacesUtils.ptm.createItem(uri, -1, -1, title)); + transactions.push(PlacesUIUtils.ptm.createItem(uri, -1, -1, title)); } return transactions; }, @@ -973,8 +973,8 @@ var BookmarkPropertiesPanel = { if (description) annotations.push(this._getDescriptionAnnotation(description)); - return PlacesUtils.ptm.createFolder(folderName, aContainer, aIndex, - annotations, childItemsTransactions); + return PlacesUIUtils.ptm.createFolder(folderName, aContainer, aIndex, + annotations, childItemsTransactions); }, /** @@ -984,16 +984,16 @@ var BookmarkPropertiesPanel = { _getCreateNewLivemarkTransaction: function BPP__getCreateNewLivemarkTransaction(aContainer, aIndex) { var feedURIString = this._element("feedLocationTextfield").value; - var feedURI = PlacesUtils.createFixedURI(feedURIString); + var feedURI = PlacesUIUtils.createFixedURI(feedURIString); var siteURIString = this._element("feedSiteLocationTextfield").value; var siteURI = null; if (siteURIString) - siteURI = PlacesUtils.createFixedURI(siteURIString); + siteURI = PlacesUIUtils.createFixedURI(siteURIString); var name = this._element("namePicker").value; - return PlacesUtils.ptm.createLivemark(feedURI, siteURI, name, - aContainer, aIndex); + return PlacesUIUtils.ptm.createLivemark(feedURI, siteURI, name, + aContainer, aIndex); }, /** @@ -1018,7 +1018,7 @@ var BookmarkPropertiesPanel = { // perfrom our transaction do via the transaction manager passed by the // opener so it can be undone. window.arguments[0].performed = true; - PlacesUtils.ptm.doTransaction(createTxn); + PlacesUIUtils.ptm.doTransaction(createTxn); }, onNamePickerInput: function BPP_onNamePickerInput() { @@ -1049,7 +1049,7 @@ var BookmarkPropertiesPanel = { if (!this._folderTree.place) { const FOLDER_TREE_PLACE_URI = "place:excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1&folder=" + - PlacesUtils.allBookmarksFolderId; + PlacesUIUtils.allBookmarksFolderId; this._folderTree.place = FOLDER_TREE_PLACE_URI; } diff --git a/browser/components/places/content/bookmarksPanel.js b/browser/components/places/content/bookmarksPanel.js index 5884a4d22a3..4f0b7de924d 100644 --- a/browser/components/places/content/bookmarksPanel.js +++ b/browser/components/places/content/bookmarksPanel.js @@ -37,7 +37,7 @@ function init() { document.getElementById("bookmarks-view").place = - "place:queryType=1&folder=" + window.top.PlacesUtils.allBookmarksFolderId; + "place:queryType=1&folder=" + window.top.PlacesUIUtils.allBookmarksFolderId; document.getElementById("search-box").focus(); } diff --git a/browser/components/places/content/controller.js b/browser/components/places/content/controller.js index ff470ae38a7..3ff5a0d1ebb 100755 --- a/browser/components/places/content/controller.js +++ b/browser/components/places/content/controller.js @@ -103,9 +103,9 @@ PlacesController.prototype = { isCommandEnabled: function PC_isCommandEnabled(aCommand) { switch (aCommand) { case "cmd_undo": - return PlacesUtils.ptm.numberOfUndoItems > 0; + return PlacesUIUtils.ptm.numberOfUndoItems > 0; case "cmd_redo": - return PlacesUtils.ptm.numberOfRedoItems > 0; + return PlacesUIUtils.ptm.numberOfRedoItems > 0; case "cmd_cut": case "cmd_delete": return this._hasRemovableSelection(false); @@ -152,7 +152,7 @@ PlacesController.prototype = { case "placesCmd_reloadMicrosummary": var selectedNode = this._view.selectedNode; return selectedNode && PlacesUtils.nodeIsBookmark(selectedNode) && - PlacesUtils.microsummaries.hasMicrosummary(selectedNode.itemId); + PlacesUIUtils.microsummaries.hasMicrosummary(selectedNode.itemId); case "placesCmd_reload": // Livemark containers var selectedNode = this._view.selectedNode; @@ -192,10 +192,10 @@ PlacesController.prototype = { doCommand: function PC_doCommand(aCommand) { switch (aCommand) { case "cmd_undo": - PlacesUtils.ptm.undoTransaction(); + PlacesUIUtils.ptm.undoTransaction(); break; case "cmd_redo": - PlacesUtils.ptm.redoTransaction(); + PlacesUIUtils.ptm.redoTransaction(); break; case "cmd_cut": this.cut(); @@ -213,13 +213,13 @@ PlacesController.prototype = { this.selectAll(); break; case "placesCmd_open": - PlacesUtils.openNodeIn(this._view.selectedNode, "current"); + PlacesUIUtils.openNodeIn(this._view.selectedNode, "current"); break; case "placesCmd_open:window": - PlacesUtils.openNodeIn(this._view.selectedNode, "window"); + PlacesUIUtils.openNodeIn(this._view.selectedNode, "window"); break; case "placesCmd_open:tab": - PlacesUtils.openNodeIn(this._view.selectedNode, "tab"); + PlacesUIUtils.openNodeIn(this._view.selectedNode, "tab"); break; case "placesCmd_new:folder": this.newItem("folder"); @@ -337,8 +337,8 @@ PlacesController.prototype = { // if the clipboard contains TYPE_X_MOZ_PLACE_* data, it is definitely // pasteable, with no need to unwrap all the nodes. - var flavors = PlacesUtils.placesFlavors; - var clipboard = PlacesUtils.clipboard; + var flavors = PlacesUIUtils.placesFlavors; + var clipboard = PlacesUIUtils.clipboard; var hasPlacesData = clipboard.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard); @@ -442,7 +442,7 @@ PlacesController.prototype = { uri = PlacesUtils._uri(node.uri); if (PlacesUtils.nodeIsBookmark(node)) { nodeData["bookmark"] = true; - var mss = PlacesUtils.microsummaries; + var mss = PlacesUIUtils.microsummaries; if (mss.hasMicrosummary(node.itemId)) nodeData["microsummary"] = true; else if (node.parent && @@ -628,9 +628,9 @@ PlacesController.prototype = { return; if (PlacesUtils.nodeIsFolder(node)) - PlacesUtils.showFolderProperties(node.itemId); + PlacesUIUtils.showFolderProperties(node.itemId); else if (PlacesUtils.nodeIsBookmark(node)) - PlacesUtils.showBookmarkProperties(node.itemId); + PlacesUIUtils.showBookmarkProperties(node.itemId); }, /** @@ -656,7 +656,7 @@ PlacesController.prototype = { */ reloadSelectedMicrosummary: function PC_reloadSelectedMicrosummary() { var selectedNode = this._view.selectedNode; - var mss = PlacesUtils.microsummaries; + var mss = PlacesUIUtils.microsummaries; if (mss.hasMicrosummary(selectedNode.itemId)) mss.refreshMicrosummary(selectedNode.itemId); }, @@ -688,14 +688,14 @@ PlacesController.prototype = { GetStringFromName("brandShortName"); var buttonPressed = promptService.confirmEx(window, - PlacesUtils.getString("tabs.openWarningTitle"), - PlacesUtils.getFormattedString(messageKey, + PlacesUIUtils.getString("tabs.openWarningTitle"), + PlacesUIUtils.getFormattedString(messageKey, [numTabsToOpen, brandShortName]), (promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0) + (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1), - PlacesUtils.getString(openKey), + PlacesUIUtils.getString(openKey), null, null, - PlacesUtils.getFormattedString("tabs.openWarningPromptMeBranded", + PlacesUIUtils.getFormattedString("tabs.openWarningPromptMeBranded", [brandShortName]), warnOnOpen); @@ -714,9 +714,9 @@ PlacesController.prototype = { openSelectionInTabs: function PC_openLinksInTabs(aEvent) { var node = this._view.selectedNode; if (node && PlacesUtils.nodeIsContainer(node)) - PlacesUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent); + PlacesUIUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent); else - PlacesUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent); + PlacesUIUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent); }, /** @@ -732,11 +732,11 @@ PlacesController.prototype = { var performed = false; if (aType == "bookmark") - performed = PlacesUtils.showAddBookmarkUI(null, null, null, ip); + performed = PlacesUIUtils.showAddBookmarkUI(null, null, null, ip); else if (aType == "livemark") - performed = PlacesUtils.showAddLivemarkUI(null, null, null, null, ip); + performed = PlacesUIUtils.showAddLivemarkUI(null, null, null, null, ip); else // folder - performed = PlacesUtils.showAddFolderUI(null, ip); + performed = PlacesUIUtils.showAddFolderUI(null, ip); if (performed) { // select the new item @@ -757,7 +757,7 @@ PlacesController.prototype = { throw Cr.NS_ERROR_NOT_AVAILABLE; var performed = false; - performed = PlacesUtils.showAddFolderUI(null, ip); + performed = PlacesUIUtils.showAddFolderUI(null, ip); if (performed) { // select the new item var insertedNodeId = PlacesUtils.bookmarks @@ -773,8 +773,8 @@ PlacesController.prototype = { var ip = this._view.insertionPoint; if (!ip) throw Cr.NS_ERROR_NOT_AVAILABLE; - var txn = PlacesUtils.ptm.createSeparator(ip.itemId, ip.index); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.createSeparator(ip.itemId, ip.index); + PlacesUIUtils.ptm.doTransaction(txn); // select the new item var insertedNodeId = PlacesUtils.bookmarks .getIdForItemAt(ip.itemId, ip.index); @@ -795,8 +795,8 @@ PlacesController.prototype = { */ sortFolderByName: function PC_sortFolderByName() { var itemId = PlacesUtils.getConcreteItemId(this._view.selectedNode); - var txn = PlacesUtils.ptm.sortFolderByName(itemId); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.sortFolderByName(itemId); + PlacesUIUtils.ptm.doTransaction(txn); }, /** @@ -856,7 +856,7 @@ PlacesController.prototype = { if (PlacesUtils.nodeIsFolder(node)) removedFolders.push(node); - transactions.push(PlacesUtils.ptm.removeItem(node.itemId)); + transactions.push(PlacesUIUtils.ptm.removeItem(node.itemId)); } }, @@ -873,8 +873,8 @@ PlacesController.prototype = { for (var i = ranges.length - 1; i >= 0 ; --i) this._removeRange(ranges[i], transactions); if (transactions.length > 0) { - var txn = PlacesUtils.ptm.aggregateTransactions(txnName, transactions); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.aggregateTransactions(txnName, transactions); + PlacesUIUtils.ptm.doTransaction(txn); } }, @@ -997,7 +997,7 @@ PlacesController.prototype = { var data = new TransferData(); function addData(type, overrideURI) { - data.addDataForFlavour(type, PlacesUtils._wrapString( + data.addDataForFlavour(type, PlacesUIUtils._wrapString( PlacesUtils.wrapNode(node, type, overrideURI))); } @@ -1075,7 +1075,7 @@ PlacesController.prototype = { function addData(type, data) { xferable.addDataFlavor(type); - xferable.setTransferData(type, PlacesUtils._wrapString(data), data.length * 2); + xferable.setTransferData(type, PlacesUIUtils._wrapString(data), data.length * 2); } // This order is _important_! It controls how this and other applications // select data to be inserted based on type. @@ -1089,7 +1089,7 @@ PlacesController.prototype = { addData(PlacesUtils.TYPE_HTML, htmlString); if (placeString || unicodeString || htmlString || mozURLString) { - PlacesUtils.clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard); + PlacesUIUtils.clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard); } } finally { @@ -1116,6 +1116,7 @@ PlacesController.prototype = { // clipboard. We need to get all of that data and build edit transactions // for them. This means asking the clipboard once for each type and // aggregating the results. + dump("PASTING\n"); /** * Constructs a transferable that can receive data of specific types. @@ -1133,7 +1134,7 @@ PlacesController.prototype = { return xferable; } - var clipboard = PlacesUtils.clipboard; + var clipboard = PlacesUIUtils.clipboard; var ip = this._view.insertionPoint; if (!ip) @@ -1161,9 +1162,9 @@ PlacesController.prototype = { // transactions insert differently if index == -1 if (ip.index > -1) index = ip.index + i; - transactions.push(PlacesUtils.makeTransaction(items[i], type.value, - ip.itemId, index, - true)); + transactions.push(PlacesUIUtils.makeTransaction(items[i], type.value, + ip.itemId, index, + true)); } return transactions; } @@ -1182,8 +1183,8 @@ PlacesController.prototype = { var transactions = getTransactions([PlacesUtils.TYPE_X_MOZ_PLACE, PlacesUtils.TYPE_X_MOZ_URL, PlacesUtils.TYPE_UNICODE]); - var txn = PlacesUtils.ptm.aggregateTransactions("Paste", transactions); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.aggregateTransactions("Paste", transactions); + PlacesUIUtils.ptm.doTransaction(txn); // select the pasted items, they should be consecutive var insertedNodeIds = []; @@ -1243,7 +1244,7 @@ var PlacesControllerDragHelper = { canDrop: function PCDH_canDrop() { var session = this.getSession(); if (session) { - var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES; + var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES; for (var i = 0; i < types.length; ++i) { if (session.isDataFlavorSupported(types[i])) return true; @@ -1263,7 +1264,7 @@ var PlacesControllerDragHelper = { _initTransferable: function PCDH__initTransferable(session) { var xferable = Cc["@mozilla.org/widget/transferable;1"]. createInstance(Ci.nsITransferable); - var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES; + var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES; for (var i = 0; i < types.length; ++i) { if (session.isDataFlavorSupported(types[i])) xferable.addDataFlavor(types[i]); @@ -1306,13 +1307,13 @@ var PlacesControllerDragHelper = { movedCount++; } - transactions.push(PlacesUtils.makeTransaction(unwrapped, + transactions.push(PlacesUIUtils.makeTransaction(unwrapped, flavor.value, insertionPoint.itemId, index, copy)); } - var txn = PlacesUtils.ptm.aggregateTransactions("DropItems", transactions); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.aggregateTransactions("DropItems", transactions); + PlacesUIUtils.ptm.doTransaction(txn); } }; diff --git a/browser/components/places/content/editBookmarkOverlay.js b/browser/components/places/content/editBookmarkOverlay.js index d957f9f3a52..586805568c7 100644 --- a/browser/components/places/content/editBookmarkOverlay.js +++ b/browser/components/places/content/editBookmarkOverlay.js @@ -145,7 +145,7 @@ var gEditItemOverlay = { // description field this._initTextField("descriptionField", - PlacesUtils.getItemDescription(this._itemId)); + PlacesUIUtils.getItemDescription(this._itemId)); this._showHideRows(); @@ -324,8 +324,8 @@ var gEditItemOverlay = { try { if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK && !this._readOnly) - this._microsummaries = PlacesUtils.microsummaries - .getMicrosummaries(this._uri, -1); + this._microsummaries = PlacesUIUtils.microsummaries + .getMicrosummaries(this._uri, -1); } catch(ex) { // getMicrosummaries will throw an exception in at least two cases: @@ -346,8 +346,8 @@ var gEditItemOverlay = { var microsummary = enumerator.getNext() .QueryInterface(Ci.nsIMicrosummary); var menuItem = this._createMicrosummaryMenuItem(microsummary); - if (PlacesUtils.microsummaries - .isMicrosummary(this._itemId, microsummary)) + if (PlacesUIUtils.microsummaries + .isMicrosummary(this._itemId, microsummary)) itemToSelect = menuItem; menupopup.appendChild(menuItem); @@ -449,12 +449,12 @@ var gEditItemOverlay = { } if (tagsToAdd.length > 0) { - var tagTxn = PlacesUtils.ptm.tagURI(this._uri, tagsToAdd); - PlacesUtils.ptm.doTransaction(tagTxn); + var tagTxn = PlacesUIUtils.ptm.tagURI(this._uri, tagsToAdd); + PlacesUIUtils.ptm.doTransaction(tagTxn); } if (tagsToRemove.length > 0) { - var untagTxn = PlacesUtils.ptm.untagURI(this._uri, tagsToRemove); - PlacesUtils.ptm.doTransaction(untagTxn); + var untagTxn = PlacesUIUtils.ptm.untagURI(this._uri, tagsToRemove); + PlacesUIUtils.ptm.doTransaction(untagTxn); } } }, @@ -470,12 +470,12 @@ var gEditItemOverlay = { var namePicker = this._element("namePicker") var txns = []; - const ptm = PlacesUtils.ptm; + const ptm = PlacesUIUtils.ptm; // Here we update either the item title or its cached static title var newTitle = this._element("userEnteredName").label; if (this._getItemStaticTitle() != newTitle) { - if (PlacesUtils.microsummaries.hasMicrosummary(this._itemId)) { + if (PlacesUIUtils.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. @@ -496,10 +496,10 @@ var gEditItemOverlay = { // bookmark previously had one, or the user selected a microsummary which // is not the one the bookmark previously had if ((newMicrosummary == null && - PlacesUtils.microsummaries.hasMicrosummary(this._itemId)) || + PlacesUIUtils.microsummaries.hasMicrosummary(this._itemId)) || (newMicrosummary != null && - !PlacesUtils.microsummaries - .isMicrosummary(this._itemId, newMicrosummary))) { + !PlacesUIUtils.microsummaries + .isMicrosummary(this._itemId, newMicrosummary))) { txns.push(ptm.editBookmarkMicrosummary(this._itemId, newMicrosummary)); } @@ -510,67 +510,67 @@ var gEditItemOverlay = { onDescriptionFieldBlur: function EIO_onDescriptionFieldInput() { var description = this._element("descriptionField").value; if (description != PlacesUtils.getItemDescription(this._itemId)) { - var txn = PlacesUtils.ptm - .editItemDescription(this._itemId, description); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm + .editItemDescription(this._itemId, description); + PlacesUIUtils.ptm.doTransaction(txn); } }, onLocationFieldBlur: function EIO_onLocationFieldBlur() { var uri; try { - uri = PlacesUtils.createFixedURI(this._element("locationField").value); + uri = PlacesUIUtils.createFixedURI(this._element("locationField").value); } catch(ex) { return; } if (!this._uri.equals(uri)) { - var txn = PlacesUtils.ptm.editBookmarkURI(this._itemId, uri); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.editBookmarkURI(this._itemId, uri); + PlacesUIUtils.ptm.doTransaction(txn); } }, onKeywordFieldBlur: function EIO_onKeywordFieldBlur() { var keyword = this._element("keywordField").value; if (keyword != PlacesUtils.bookmarks.getKeywordForBookmark(this._itemId)) { - var txn = PlacesUtils.ptm.editBookmarkKeyword(this._itemId, keyword); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.editBookmarkKeyword(this._itemId, keyword); + PlacesUIUtils.ptm.doTransaction(txn); } }, onFeedLocationFieldBlur: function EIO_onFeedLocationFieldBlur() { var uri; try { - uri = PlacesUtils.createFixedURI(this._element("feedLocationField").value); + uri = PlacesUIUtils.createFixedURI(this._element("feedLocationField").value); } catch(ex) { return; } var currentFeedURI = PlacesUtils.livemarks.getFeedURI(this._itemId); if (!currentFeedURI.equals(uri)) { - var txn = PlacesUtils.ptm.editLivemarkFeedURI(this._itemId, uri); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.editLivemarkFeedURI(this._itemId, uri); + PlacesUIUtils.ptm.doTransaction(txn); } }, onSiteLocationFieldBlur: function EIO_onSiteLocationFieldBlur() { var uri = null; try { - uri = PlacesUtils.createFixedURI(this._element("siteLocationField").value); + uri = PlacesUIUtils.createFixedURI(this._element("siteLocationField").value); } catch(ex) { } var currentSiteURI = PlacesUtils.livemarks.getSiteURI(this._itemId); if (!uri || !currentSiteURI.equals(uri)) { - var txn = PlacesUtils.ptm.editLivemarkSiteURI(this._itemId, uri); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.editLivemarkSiteURI(this._itemId, uri); + PlacesUIUtils.ptm.doTransaction(txn); } }, onLoadInSidebarCheckboxCommand: function EIO_onLoadInSidebarCheckboxCommand() { var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked; - var txn = PlacesUtils.ptm.setLoadInSidebar(this._itemId, - loadInSidebarChecked); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.setLoadInSidebar(this._itemId, + loadInSidebarChecked); + PlacesUIUtils.ptm.doTransaction(txn); }, toggleFolderTreeVisibility: function EIO_toggleFolderTreeVisibility() { @@ -591,7 +591,7 @@ var gEditItemOverlay = { if (!this._folderTree.place) { const FOLDER_TREE_PLACE_URI = "place:excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1&folder=" + - window.top.PlacesUtils.allBookmarksFolderId; + window.top.PlacesUIUtils.allBookmarksFolderId; this._folderTree.place = FOLDER_TREE_PLACE_URI; } @@ -651,8 +651,8 @@ var gEditItemOverlay = { // Move the item var container = this._getFolderIdFromMenuList(); if (PlacesUtils.bookmarks.getFolderIdForItem(this._itemId) != container) { - var txn = PlacesUtils.ptm.moveItem(this._itemId, container, -1); - PlacesUtils.ptm.doTransaction(txn); + var txn = PlacesUIUtils.ptm.moveItem(this._itemId, container, -1); + PlacesUIUtils.ptm.doTransaction(txn); // Mark the containing folder as recently-used if it isn't in the // static list diff --git a/browser/components/places/content/history-panel.js b/browser/components/places/content/history-panel.js index cd52ec41c10..e83a049924b 100644 --- a/browser/components/places/content/history-panel.js +++ b/browser/components/places/content/history-panel.js @@ -104,7 +104,7 @@ function historyAddBookmarks() // or if the selected item is not a URI node var node = gHistoryTree.selectedNode; if (node && PlacesUtils.nodeIsURI(node)) - PlacesUtils.showMinimalAddBookmarkUI(PlacesUtils._uri(node.uri), node.title); + PlacesUIUtils.showMinimalAddBookmarkUI(PlacesUtils._uri(node.uri), node.title); } function searchHistory(aInput) diff --git a/browser/components/places/content/menu.xml b/browser/components/places/content/menu.xml index e824d538abe..29d1477d0e1 100755 --- a/browser/components/places/content/menu.xml +++ b/browser/components/places/content/menu.xml @@ -215,7 +215,7 @@ @@ -601,7 +601,7 @@ + oncommand="PlacesOrganizer.onRestoreBookmarksFromFile();"/> 0) @@ -832,7 +832,7 @@ PlacesTreeView.prototype = { { var uri = aNode.uri; NS_ASSERT(uri, "if there is no uri, we can't persist the open state"); - return uri ? PlacesUtils.RDF.GetResource(uri) : null; + return uri ? PlacesUIUtils.RDF.GetResource(uri) : null; }, // nsITreeView @@ -1129,7 +1129,7 @@ PlacesTreeView.prototype = { // if they go through the "result" API. if (PlacesUtils.nodeIsSeparator(node)) return ""; - return node.title || PlacesUtils.getString("noTitle"); + return node.title || PlacesUIUtils.getString("noTitle"); case this.COLUMN_TYPE_TAGS: return node.tags; case this.COLUMN_TYPE_URI: @@ -1203,13 +1203,13 @@ PlacesTreeView.prototype = { var resource = this._getResourceForNode(node); if (resource) { - const openLiteral = PlacesUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open"); - const trueLiteral = PlacesUtils.RDF.GetLiteral("true"); + const openLiteral = PlacesUIUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open"); + const trueLiteral = PlacesUIUtils.RDF.GetLiteral("true"); if (node.containerOpen) - PlacesUtils.localStore.Unassert(resource, openLiteral, trueLiteral); + PlacesUIUtils.localStore.Unassert(resource, openLiteral, trueLiteral); else - PlacesUtils.localStore.Assert(resource, openLiteral, trueLiteral, true); + PlacesUIUtils.localStore.Assert(resource, openLiteral, trueLiteral, true); } node.containerOpen = !node.containerOpen; diff --git a/browser/components/places/content/utils.js b/browser/components/places/content/utils.js index b46d541c721..57be740d968 100644 --- a/browser/components/places/content/utils.js +++ b/browser/components/places/content/utils.js @@ -23,6 +23,7 @@ * Myk Melez * Asaf Romano * Sungjoon Steve Won + * Dietrich Ayala * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -46,16 +47,20 @@ var Ci = Components.interfaces; var Cc = Components.classes; var Cr = Components.results; -Components.utils.import("resource://gre/modules/JSON.jsm"); +#include ../../../../toolkit/content/debug.js +#include ../../../../toolkit/components/places/src/utils.js const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar"; const DESCRIPTION_ANNO = "bookmarkProperties/description"; -const POST_DATA_ANNO = "bookmarkProperties/POSTData"; -const LMANNO_FEEDURI = "livemark/feedURI"; -const LMANNO_SITEURI = "livemark/siteURI"; const ORGANIZER_FOLDER_ANNO = "PlacesOrganizer/OrganizerFolder"; const ORGANIZER_QUERY_ANNO = "PlacesOrganizer/OrganizerQuery"; +/* +XXX PULLED IN BY TOOLKIT UTILS.JS + +const LMANNO_FEEDURI = "livemark/feedURI"; +const LMANNO_SITEURI = "livemark/siteURI"; + #ifdef XP_MACOSX // On Mac OSX, the transferable system converts "\r\n" to "\n\n", where we // really just want "\n". @@ -64,6 +69,7 @@ const NEWLINE= "\n"; // On other platforms, the transferable system converts "\r\n" to "\n". const NEWLINE = "\r\n"; #endif +*/ function QI_node(aNode, aIID) { var result = null; @@ -80,71 +86,7 @@ function asFullVisit(aNode){ return QI_node(aNode, Ci.nsINavHistoryFullVisitResu function asContainer(aNode){ return QI_node(aNode, Ci.nsINavHistoryContainerResultNode);} function asQuery(aNode) { return QI_node(aNode, Ci.nsINavHistoryQueryResultNode); } -var PlacesUtils = { - // Place entries that are containers, e.g. bookmark folders or queries. - TYPE_X_MOZ_PLACE_CONTAINER: "text/x-moz-place-container", - // Place entries that are bookmark separators. - TYPE_X_MOZ_PLACE_SEPARATOR: "text/x-moz-place-separator", - // Place entries that are not containers or separators - TYPE_X_MOZ_PLACE: "text/x-moz-place", - // Place entries in shortcut url format (url\ntitle) - TYPE_X_MOZ_URL: "text/x-moz-url", - // Place entries formatted as HTML anchors - TYPE_HTML: "text/html", - // Place entries as raw URL text - TYPE_UNICODE: "text/unicode", - - /** - * The Bookmarks Service. - */ - get bookmarks() { - delete this.bookmarks; - return this.bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); - }, - - /** - * The Nav History Service. - */ - get history() { - delete this.history; - return this.history = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsINavHistoryService); - }, - - get globalHistory() { - delete this.globalHistory; - return this.globalHistory = Cc["@mozilla.org/browser/global-history;2"]. - getService(Ci.nsIBrowserHistory); - }, - - /** - * The Live Bookmark Service. - */ - get livemarks() { - delete this.livemarks; - return this.livemarks = Cc["@mozilla.org/browser/livemark-service;2"]. - getService(Ci.nsILivemarkService); - }, - - /** - * The Annotations Service. - */ - get annotations() { - delete this.annotations; - return this.annotations = Cc["@mozilla.org/browser/annotation-service;1"]. - getService(Ci.nsIAnnotationService); - }, - - /** - * The Favicons Service - */ - get favicons() { - delete this.favicons; - return this.favicons = Cc["@mozilla.org/browser/favicon-service;1"]. - getService(Ci.nsIFaviconService); - }, - +var PlacesUIUtils = { /** * The Microsummary Service */ @@ -154,15 +96,6 @@ var PlacesUtils = { getService(Ci.nsIMicrosummaryService); }, - /** - * The Places Tagging Service - */ - get tagging() { - delete this.tagging; - return this.tagging = Cc["@mozilla.org/browser/tagging-service;1"]. - getService(Ci.nsITaggingService); - }, - get RDF() { delete this.RDF; return this.RDF = Cc["@mozilla.org/rdf/rdf-service;1"]. @@ -192,19 +125,6 @@ var PlacesUtils = { getService(Ci.nsIURIFixup); }, - /** - * Makes a URI from a spec. - * @param aSpec - * The string spec of the URI - * @returns A URI object for the spec. - */ - _uri: function PU__uri(aSpec) { - NS_ASSERT(aSpec, "empty URL spec"); - return Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService). - newURI(aSpec, null, null); - }, - /** * Makes a URI from a spec, and do fixup * @param aSpec @@ -248,416 +168,6 @@ var PlacesUtils = { return this._bundle.GetStringFromName(key); }, - /** - * Determines whether or not a ResultNode is a Bookmark folder. - * @param aNode - * A result node - * @returns true if the node is a Bookmark folder, false otherwise - */ - nodeIsFolder: function PU_nodeIsFolder(aNode) { - NS_ASSERT(aNode, "null node"); - return (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER || - aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT); - }, - - /** - * Determines whether or not a ResultNode represents a bookmarked URI. - * @param aNode - * A result node - * @returns true if the node represents a bookmarked URI, false otherwise - */ - nodeIsBookmark: function PU_nodeIsBookmark(aNode) { - NS_ASSERT(aNode, "null node"); - return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_URI && - aNode.itemId != -1; - }, - - /** - * Determines whether or not a ResultNode is a Bookmark separator. - * @param aNode - * A result node - * @returns true if the node is a Bookmark separator, false otherwise - */ - nodeIsSeparator: function PU_nodeIsSeparator(aNode) { - NS_ASSERT(aNode, "null node"); - - return (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR); - }, - - /** - * Determines whether or not a ResultNode is a visit item. - * @param aNode - * A result node - * @returns true if the node is a visit item, false otherwise - */ - nodeIsVisit: function PU_nodeIsVisit(aNode) { - NS_ASSERT(aNode, "null node"); - - const NHRN = Ci.nsINavHistoryResultNode; - var type = aNode.type; - return type == NHRN.RESULT_TYPE_VISIT || - type == NHRN.RESULT_TYPE_FULL_VISIT; - }, - - /** - * Determines whether or not a ResultNode is a URL item. - * @param aNode - * A result node - * @returns true if the node is a URL item, false otherwise - */ - uriTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_URI, - Ci.nsINavHistoryResultNode.RESULT_TYPE_VISIT, - Ci.nsINavHistoryResultNode.RESULT_TYPE_FULL_VISIT], - nodeIsURI: function PU_nodeIsURI(aNode) { - NS_ASSERT(aNode, "null node"); - return this.uriTypes.indexOf(aNode.type) != -1; - }, - - /** - * Determines whether or not a ResultNode is a Query item. - * @param aNode - * A result node - * @returns true if the node is a Query item, false otherwise - */ - nodeIsQuery: function PU_nodeIsQuery(aNode) { - NS_ASSERT(aNode, "null node"); - return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY; - }, - - /** - * Determines if a node is read only (children cannot be inserted, sometimes - * they cannot be removed depending on the circumstance) - * @param aNode - * A result node - * @returns true if the node is readonly, false otherwise - */ - nodeIsReadOnly: function PU_nodeIsReadOnly(aNode) { - NS_ASSERT(aNode, "null node"); - - if (this.nodeIsFolder(aNode)) - return this.bookmarks.getFolderReadonly(asQuery(aNode).folderItemId); - if (this.nodeIsQuery(aNode)) - return asQuery(aNode).childrenReadOnly; - return false; - }, - - /** - * Determines whether or not a ResultNode is a host container. - * @param aNode - * A result node - * @returns true if the node is a host container, false otherwise - */ - nodeIsHost: function PU_nodeIsHost(aNode) { - NS_ASSERT(aNode, "null node"); - return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY && - aNode.parent && - asQuery(aNode.parent).queryOptions.resultType == - Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY; - }, - - /** - * Determines whether or not a ResultNode is a day container. - * @param node - * A NavHistoryResultNode - * @returns true if the node is a day container, false otherwise - */ - nodeIsDay: function PU_nodeIsDay(aNode) { - NS_ASSERT(aNode, "null node"); - var resultType; - return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY && - aNode.parent && - ((resultType = asQuery(aNode.parent).queryOptions.resultType) == - Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY || - resultType == Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY); - }, - - /** - * Determines whether or not a ResultNode is a container. - * @param aNode - * A result node - * @returns true if the node is a container item, false otherwise - */ - containerTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER, - Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT, - Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY, - Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER], - nodeIsContainer: function PU_nodeIsContainer(aNode) { - NS_ASSERT(aNode, "null node"); - return this.containerTypes.indexOf(aNode.type) != -1; - }, - - /** - * Determines whether or not a result-node is a dynamic-container item. - * The dynamic container result node type is for dynamically created - * containers (e.g. for the file browser service where you get your folders - * in bookmark menus). - * @param aNode - * A result node - * @returns true if the node is a dynamic container item, false otherwise - */ - nodeIsDynamicContainer: function PU_nodeIsDynamicContainer(aNode) { - NS_ASSERT(aNode, "null node"); - if (aNode.type == NHRN.RESULT_TYPE_DYNAMIC_CONTAINER) - return true; - return false; - }, - - /** - * Determines whether a result node is a remote container registered by the - * livemark service. - * @param aNode - * A result Node - * @returns true if the node is a livemark container item - */ - nodeIsLivemarkContainer: function PU_nodeIsLivemarkContainer(aNode) { - // Use the annotations service directly to avoid instantiating - // the Livemark service on startup. (bug 398300) - return this.nodeIsFolder(aNode) && - this.annotations.itemHasAnnotation(aNode.itemId, LMANNO_FEEDURI); - }, - - /** - * Determines whether a result node is a live-bookmark item - * @param aNode - * A result node - * @returns true if the node is a livemark container item - */ - nodeIsLivemarkItem: function PU_nodeIsLivemarkItem(aNode) { - return aNode.parent && this.nodeIsLivemarkContainer(aNode.parent); - }, - - /** - * Determines whether or not a node is a readonly folder. - * @param aNode - * The node to test. - * @returns true if the node is a readonly folder. - */ - isReadonlyFolder: function(aNode) { - NS_ASSERT(aNode, "null node"); - - return this.nodeIsFolder(aNode) && - this.bookmarks.getFolderReadonly(asQuery(aNode).folderItemId); - }, - - /** - * Gets the concrete item-id for the given node. Generally, this is just - * node.itemId, but for folder-shortcuts that's node.folderItemId. - */ - getConcreteItemId: function PU_getConcreteItemId(aNode) { - if (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT) - return asQuery(aNode).folderItemId; - return aNode.itemId; - }, - - /** - * Gets the index of a node within its parent container - * @param aNode - * The node to look up - * @returns The index of the node within its parent container, or -1 if the - * node was not found or the node specified has no parent. - */ - getIndexOfNode: function PU_getIndexOfNode(aNode) { - NS_ASSERT(aNode, "null node"); - - var parent = aNode.parent; - if (!parent) - return -1; - var wasOpen = parent.containerOpen; - var result, oldViewer; - if (!wasOpen) { - result = parent.parentResult; - oldViewer = result.viewer; - result.viewer = null; - parent.containerOpen = true; - } - var cc = parent.childCount; - for (var i = 0; i < cc && parent.getChild(i) != aNode; ++i); - if (!wasOpen) { - parent.containerOpen = false; - result.viewer = oldViewer; - } - return i < cc ? i : -1; - }, - - /** - * String-wraps a result node according to the rules of the specified - * content type. - * @param aNode - * The Result node to wrap (serialize) - * @param aType - * The content type to serialize as - * @param [optional] aOverrideURI - * Used instead of the node's URI if provided. - * This is useful for wrapping a container as TYPE_X_MOZ_URL, - * TYPE_HTML or TYPE_UNICODE. - * @returns A string serialization of the node - */ - wrapNode: function PU_wrapNode(aNode, aType, aOverrideURI) { - var 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 - function convertNode(cNode) { - try { - if (self.nodeIsFolder(cNode) && cNode.queryOptions.excludeItems) - return self.getFolderContents(cNode.itemId, false, true).root; - } - catch (e) { - } - return cNode; - } - - switch (aType) { - case this.TYPE_X_MOZ_PLACE: - case this.TYPE_X_MOZ_PLACE_SEPARATOR: - case this.TYPE_X_MOZ_PLACE_CONTAINER: - function gatherDataPlace(bNode) { - var nodeId = 0; - if (bNode.itemId != -1) - nodeId = bNode.itemId; - var nodeUri = bNode.uri - var nodeTitle = bNode.title; - var nodeParentId = 0; - if (bNode.parent && self.nodeIsFolder(bNode.parent)) - nodeParentId = bNode.parent.itemId; - var nodeIndex = self.getIndexOfNode(bNode); - var nodeKeyword = self.bookmarks.getKeywordForBookmark(bNode.itemId); - var nodeAnnos = self.getAnnotationsForItem(bNode.itemId); - var nodeType = ""; - if (self.nodeIsContainer(bNode)) - nodeType = self.TYPE_X_MOZ_PLACE_CONTAINER; - else if (self.nodeIsURI(bNode)) // a bookmark or a history visit - nodeType = self.TYPE_X_MOZ_PLACE; - else if (self.nodeIsSeparator(bNode)) - nodeType = self.TYPE_X_MOZ_PLACE_SEPARATOR; - - var node = { id: nodeId, - uri: nodeUri, - title: nodeTitle, - parent: nodeParentId, - index: nodeIndex, - keyword: nodeKeyword, - annos: nodeAnnos, - type: nodeType }; - - // Recurse down children if the node is a folder - if (self.nodeIsContainer(bNode)) { - asContainer(bNode); - if (self.nodeIsLivemarkContainer(bNode)) { - // just save the livemark info, reinstantiate on other end - var feedURI = self.livemarks.getFeedURI(bNode.itemId).spec; - var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec; - node.uri = { feed: feedURI, - site: siteURI }; - } - else { // bookmark folders + history containers - var wasOpen = bNode.containerOpen; - if (!wasOpen) - bNode.containerOpen = true; - var childNodes = []; - var cc = bNode.childCount; - for (var i = 0; i < cc; ++i) { - var childObj = gatherDataPlace(bNode.getChild(i)); - if (childObj != null) - childNodes.push(childObj); - } - var parent = node; - node = { folder: parent, - children: childNodes, - type: self.TYPE_X_MOZ_PLACE_CONTAINER }; - bNode.containerOpen = wasOpen; - } - } - return node; - } - return JSON.toString(gatherDataPlace(convertNode(aNode))); - - case this.TYPE_X_MOZ_URL: - function gatherDataUrl(bNode) { - if (self.nodeIsLivemarkContainer(bNode)) { - var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec; - return siteURI + NEWLINE + bNode.title; - } - if (self.nodeIsURI(bNode)) - return (aOverrideURI || bNode.uri) + NEWLINE + bNode.title; - // ignore containers and separators - items without valid URIs - return ""; - } - return gatherDataUrl(convertNode(aNode)); - - case this.TYPE_HTML: - function gatherDataHtml(bNode) { - function htmlEscape(s) { - s = s.replace(/&/g, "&"); - s = s.replace(/>/g, ">"); - s = s.replace(/" + escapedTitle + "" + NEWLINE; - } - if (self.nodeIsContainer(bNode)) { - asContainer(bNode); - var wasOpen = bNode.containerOpen; - if (!wasOpen) - bNode.containerOpen = true; - - var childString = "
" + escapedTitle + "
" + NEWLINE; - var cc = bNode.childCount; - for (var i = 0; i < cc; ++i) - childString += "
" - + NEWLINE - + gatherDataHtml(bNode.getChild(i)) - + "
" - + NEWLINE; - bNode.containerOpen = wasOpen; - return childString + "
" + NEWLINE; - } - if (self.nodeIsURI(bNode)) - return "" + escapedTitle + "" + NEWLINE; - if (self.nodeIsSeparator(bNode)) - return "
" + NEWLINE; - return ""; - } - return gatherDataHtml(convertNode(aNode)); - } - // case this.TYPE_UNICODE: - function gatherDataText(bNode) { - if (self.nodeIsLivemarkContainer(bNode)) - return self.livemarks.getSiteURI(bNode.itemId).spec; - if (self.nodeIsContainer(bNode)) { - asContainer(bNode); - var wasOpen = bNode.containerOpen; - if (!wasOpen) - bNode.containerOpen = true; - - var childString = bNode.title + NEWLINE; - var cc = bNode.childCount; - for (var i = 0; i < cc; ++i) { - var child = bNode.getChild(i); - var suffix = i < (cc - 1) ? NEWLINE : ""; - childString += gatherDataText(child) + suffix; - } - bNode.containerOpen = wasOpen; - return childString; - } - if (self.nodeIsURI(bNode)) - return (aOverrideURI || bNode.uri); - if (self.nodeIsSeparator(bNode)) - return "--------------------"; - return ""; - } - - return gatherDataText(convertNode(aNode)); - }, - /** * Get a transaction for copying a uri item from one container to another * as a bookmark. @@ -670,7 +180,7 @@ var PlacesUtils = { * @returns A nsITransaction object that performs the copy. */ _getURIItemCopyTransaction: function (aData, aContainer, aIndex) { - return this.ptm.createItem(this._uri(aData.uri), aContainer, aIndex, + return this.ptm.createItem(PlacesUtils._uri(aData.uri), aContainer, aIndex, aData.title, ""); }, @@ -691,15 +201,14 @@ var PlacesUtils = { _getBookmarkItemCopyTransaction: function PU__getBookmarkItemCopyTransaction(aData, aContainer, aIndex, aExcludeAnnotations) { - var itemURL = this._uri(aData.uri); + var itemURL = PlacesUtils._uri(aData.uri); var itemTitle = aData.title; - var keyword = aData.keyword; - var annos = aData.annos; + var keyword = aData.keyword || null; + var annos = aData.annos || []; if (aExcludeAnnotations) { - annos = - annos.filter(function(aValue, aIndex, aArray) { - return aExcludeAnnotations.indexOf(aValue.name) == -1; - }); + annos = annos.filter(function(aValue, aIndex, aArray) { + return aExcludeAnnotations.indexOf(aValue.name) == -1; + }); } var childTxns = []; if (aData.dateAdded) @@ -739,25 +248,23 @@ var PlacesUtils = { if (aIndex > -1) index = aIndex + i; - if (node.type == self.TYPE_X_MOZ_PLACE_CONTAINER) { - if (node.folder) { - var title = node.folder.title; - var annos = node.folder.annos; - var folderItemsTransactions = - getChildItemsTransactions(node.children); - txn = self.ptm.createFolder(title, -1, index, annos, + if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER) { + if (node.livemark && node.annos) // node is a livemark + txn = self._getLivemarkCopyTransaction(node, aContainer, index); + else { + var folderItemsTransactions = []; + if (node.dateAdded) + folderItemsTransactions.push(self.ptm.editItemDateAdded(null, node.dateAdded)); + if (node.lastModified) + folderItemsTransactions.push(self.ptm.editItemLastModified(null, node.lastModified)); + var annos = node.annos || []; + txn = self.ptm.createFolder(node.title, -1, index, annos, folderItemsTransactions); } - else { // node is a livemark - var feedURI = self._uri(node.uri.feed); - var siteURI = self._uri(node.uri.site); - txn = self.ptm.createLivemark(feedURI, siteURI, node.title, - aContainer, index, node.annos); - } } - else if (node.type == self.TYPE_X_MOZ_PLACE_SEPARATOR) + else if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR) txn = self.ptm.createSeparator(-1, index); - else if (node.type == self.TYPE_X_MOZ_PLACE) + else if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE) txn = self._getBookmarkItemCopyTransaction(node, -1, index); NS_ASSERT(txn, "Unexpected item under a bookmarks folder"); @@ -767,75 +274,51 @@ var PlacesUtils = { return childItemsTransactions; } - var title = aData.folder.title; - var annos = aData.folder.annos; - var childItems = getChildItemsTransactions(aData.children); - if (aData.folder.dateAdded) - childItems.push(this.ptm.editItemDateAdded(null, aData.folder.dateAdded)); - if (aData.folder.lastModified) - childItems.push(this.ptm.editItemLastModified(null, aData.folder.lastModified)); - return this.ptm.createFolder(title, aContainer, aIndex, annos, childItems); + // tag folders use tag transactions + if (aContainer == PlacesUtils.bookmarks.tagsFolder) { + var txns = []; + if (aData.children) { + aData.children.forEach(function(aChild) { + txns.push(this.ptm.tagURI(PlacesUtils._uri(aChild.uri), [aData.title])); + }, this); + } + return this.ptm.aggregateTransactions("addTags", txns); + } + else if (aData.livemark && aData.annos) { + // Place is a Livemark Container + return this._getLivemarkCopyTransaction(aData, aContainer, aIndex); + } + else { + var childItems = getChildItemsTransactions(aData.children); + if (aData.dateAdded) + childItems.push(this.ptm.editItemDateAdded(null, aData.dateAdded)); + if (aData.lastModified) + childItems.push(this.ptm.editItemLastModified(null, aData.lastModified)); + + var annos = aData.annos || []; + return this.ptm.createFolder(aData.title, aContainer, aIndex, annos, childItems); + } }, - /** - * Unwraps data from the Clipboard or the current Drag Session. - * @param blob - * A blob (string) of data, in some format we potentially know how - * to parse. - * @param type - * The content type of the blob. - * @returns An array of objects representing each item contained by the source. - */ - unwrapNodes: function PU_unwrapNodes(blob, type) { - // We split on "\n" because the transferable system converts "\r\n" to "\n" - var nodes = []; - switch(type) { - case this.TYPE_X_MOZ_PLACE: - case this.TYPE_X_MOZ_PLACE_SEPARATOR: - case this.TYPE_X_MOZ_PLACE_CONTAINER: - nodes = JSON.fromString("[" + blob + "]"); - break; - case this.TYPE_X_MOZ_URL: - var parts = blob.split("\n"); - // data in this type has 2 parts per entry, so if there are fewer - // than 2 parts left, the blob is malformed and we should stop - // but drag and drop of files from the shell has parts.length = 1 - if (parts.length != 1 && parts.length % 2) - break; - for (var i = 0; i < parts.length; i=i+2) { - var uriString = parts[i]; - var titleString = ""; - if (parts.length > i+1) - titleString = parts[i+1]; - else { - // for drag and drop of files, try to use the leafName as title - try { - titleString = this._uri(uriString).QueryInterface(Ci.nsIURL) - .fileName; - } - catch (e) {} - } - // note: this._uri() will throw if uriString is not a valid URI - if (this._uri(uriString)) { - nodes.push({ uri: uriString, - title: titleString ? titleString : uriString }); - } - } - break; - case this.TYPE_UNICODE: - var parts = blob.split("\n"); - for (var i = 0; i < parts.length; i++) { - var uriString = parts[i]; - // note: this._uri() will throw if uriString is not a valid URI - if (uriString != "" && this._uri(uriString)) - nodes.push({ uri: uriString, title: uriString }); - } - break; - default: - LOG("Cannot unwrap data of type " + type); - throw Cr.NS_ERROR_INVALID_ARG; - } - return nodes; + _getLivemarkCopyTransaction: + function PU__getLivemarkCopyTransaction(aData, aContainer, aIndex) { + NS_ASSERT(aData.livemark && aData.annos, "node is not a livemark"); + // Place is a Livemark Container + var feedURI = null; + var siteURI = null; + aData.annos = aData.annos.filter(function(aAnno) { + if (aAnno.name == LMANNO_FEEDURI) { + feedURI = this._uri(aAnno.value); + return false; + } + else if (aAnno.name == LMANNO_SITEURI) { + siteURI = this._uri(aAnno.value); + return false; + } + return true; + }, this); + return this.ptm.createLivemark(feedURI, siteURI, aData.title, aContainer, + aIndex, aData.annos); }, /** @@ -857,81 +340,42 @@ var PlacesUtils = { makeTransaction: function PU_makeTransaction(data, type, container, index, copy) { switch (data.type) { - case this.TYPE_X_MOZ_PLACE_CONTAINER: - if (data.folder) { - // Place is a folder. + case PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER: if (copy) return this._getFolderCopyTransaction(data, container, index); - } - else if (copy) { - // Place is a Livemark Container, should be reinstantiated - var feedURI = this._uri(data.uri.feed); - var siteURI = this._uri(data.uri.site); - return this.ptm.createLivemark(feedURI, siteURI, data.title, container, - index, data.annos); - } - break; - case this.TYPE_X_MOZ_PLACE: - if (data.id <= 0) - return this._getURIItemCopyTransaction(data, container, index); - - if (copy) { - // Copying a child of a live-bookmark by itself should result - // as a new normal bookmark item (bug 376731) - var copyBookmarkAnno = - this._getBookmarkItemCopyTransaction(data, container, index, - ["livemark/bookmarkFeedURI"]); - return copyBookmarkAnno; - } - break; - case this.TYPE_X_MOZ_PLACE_SEPARATOR: - if (copy) { + else { // Move the item + var id = data.folder ? data.folder.id : data.id; + return this.ptm.moveItem(id, container, index); + } + break; + case PlacesUtils.TYPE_X_MOZ_PLACE: + if (data.id <= 0) // non-bookmark item + return this._getURIItemCopyTransaction(data, container, index); + + if (copy) { + // Copying a child of a live-bookmark by itself should result + // as a new normal bookmark item (bug 376731) + var copyBookmarkAnno = + this._getBookmarkItemCopyTransaction(data, container, index, + ["livemark/bookmarkFeedURI"]); + return copyBookmarkAnno; + } + else + return this.ptm.moveItem(data.id, container, index); + break; + case PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR: // There is no data in a separator, so copying it just amounts to // inserting a new separator. return this.ptm.createSeparator(container, index); - } - break; - default: - if (type == this.TYPE_X_MOZ_URL || type == this.TYPE_UNICODE) { - var title = (type == this.TYPE_X_MOZ_URL) ? data.title : data.uri; - return this.ptm.createItem(this._uri(data.uri), container, index, - title); - } - return null; + break; + default: + if (type == PlacesUtils.TYPE_X_MOZ_URL || type == PlacesUtils.TYPE_UNICODE) { + var title = (type == PlacesUtils.TYPE_X_MOZ_URL) ? data.title : data.uri; + return this.ptm.createItem(PlacesUtils._uri(data.uri), container, index, + title); + } } - if (data.id <= 0) - return null; - - // Move the item otherwise - var id = data.folder ? data.folder.id : data.id; - return this.ptm.moveItem(id, container, index); - }, - - /** - * Generates a nsINavHistoryResult for the contents of a folder. - * @param folderId - * The folder to open - * @param [optional] excludeItems - * True to hide all items (individual bookmarks). This is used on - * the left places pane so you just get a folder hierarchy. - * @param [optional] expandQueries - * True to make query items expand as new containers. For managing, - * you want this to be false, for menus and such, you want this to - * be true. - * @returns A nsINavHistoryResult containing the contents of the - * folder. The result.root is guaranteed to be open. - */ - getFolderContents: - function PU_getFolderContents(aFolderId, aExcludeItems, aExpandQueries) { - var query = this.history.getNewQuery(); - query.setFolders([aFolderId], 1); - var options = this.history.getNewQueryOptions(); - options.excludeItems = aExcludeItems; - options.expandQueries = aExpandQueries; - - var result = this.history.executeQuery(query, options); - result.root.containerOpen = true; - return result; + return null; }, /** @@ -1307,7 +751,8 @@ var PlacesUtils = { * TRANSITION_LINK. */ markPageAsTyped: function PU_markPageAsTyped(aURL) { - this.globalHistory.markPageAsTyped(this.createFixedURI(aURL)); + PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory) + .markPageAsTyped(this.createFixedURI(aURL)); }, /** @@ -1318,7 +763,7 @@ var PlacesUtils = { * If we don't call this, we'll treat those visits as TRANSITION_LINK. */ markPageAsFollowedBookmark: function PU_markPageAsFollowedBookmark(aURL) { - this.history.markPageAsFollowedBookmark(this.createFixedURI(aURL)); + PlacesUtils.history.markPageAsFollowedBookmark(this.createFixedURI(aURL)); }, /** @@ -1330,8 +775,8 @@ var PlacesUtils = { * */ checkURLSecurity: function PU_checkURLSecurity(aURINode) { - if (!this.nodeIsBookmark(aURINode)) { - var uri = this._uri(aURINode.uri); + if (!PlacesUtils.nodeIsBookmark(aURINode)) { + var uri = PlacesUtils._uri(aURINode.uri); if (uri.schemeIs("javascript") || uri.schemeIs("data")) { const BRANDING_BUNDLE_URI = "chrome://branding/locale/brand.properties"; var brandShortName = Cc["@mozilla.org/intl/stringbundle;1"]. @@ -1349,137 +794,6 @@ var PlacesUtils = { return true; }, - /** - * Fetch all annotations for a URI, including all properties of each - * annotation which would be required to recreate it. - * @param aURI - * The URI for which annotations are to be retrieved. - * @return Array of objects, each containing the following properties: - * name, flags, expires, mimeType, type, value - */ - getAnnotationsForURI: function PU_getAnnotationsForURI(aURI) { - var annosvc = this.annotations; - var annos = [], val = null; - var annoNames = annosvc.getPageAnnotationNames(aURI, {}); - for (var i = 0; i < annoNames.length; i++) { - var flags = {}, exp = {}, mimeType = {}, storageType = {}; - annosvc.getPageAnnotationInfo(aURI, annoNames[i], flags, exp, mimeType, storageType); - if (storageType.value == annosvc.TYPE_BINARY) { - var data = {}, length = {}, mimeType = {}; - annosvc.getPageAnnotationBinary(aURI, annoNames[i], data, length, mimeType); - val = data.value; - } - else - val = annosvc.getPageAnnotation(aURI, annoNames[i]); - - annos.push({name: annoNames[i], - flags: flags.value, - expires: exp.value, - mimeType: mimeType.value, - type: storageType.value, - value: val}); - } - return annos; - }, - - /** - * Fetch all annotations for an item, including all properties of each - * annotation which would be required to recreate it. - * @param aItemId - * The identifier of the itme for which annotations are to be - * retrieved. - * @return Array of objects, each containing the following properties: - * name, flags, expires, mimeType, type, value - */ - getAnnotationsForItem: function PU_getAnnotationsForItem(aItemId) { - var annosvc = this.annotations; - var annos = [], val = null; - var annoNames = annosvc.getItemAnnotationNames(aItemId, {}); - for (var i = 0; i < annoNames.length; i++) { - var flags = {}, exp = {}, mimeType = {}, storageType = {}; - annosvc.getItemAnnotationInfo(aItemId, annoNames[i], flags, exp, mimeType, storageType); - if (storageType.value == annosvc.TYPE_BINARY) { - var data = {}, length = {}, mimeType = {}; - annosvc.geItemAnnotationBinary(aItemId, annoNames[i], data, length, mimeType); - val = data.value; - } - else - val = annosvc.getItemAnnotation(aItemId, annoNames[i]); - - annos.push({name: annoNames[i], - flags: flags.value, - expires: exp.value, - mimeType: mimeType.value, - type: storageType.value, - value: val}); - } - return annos; - }, - - /** - * Annotate a URI with a batch of annotations. - * @param aURI - * The URI for which annotations are to be set. - * @param aAnnotations - * Array of objects, each containing the following properties: - * name, flags, expires, type, mimeType (only used for binary - * annotations) value. - */ - setAnnotationsForURI: function PU_setAnnotationsForURI(aURI, aAnnos) { - var annosvc = this.annotations; - aAnnos.forEach(function(anno) { - var flags = ("flags" in anno) ? anno.flags : 0; - var expires = ("expires" in anno) ? - anno.expires : Ci.nsIAnnotationService.EXPIRE_NEVER; - if (anno.type == annosvc.TYPE_BINARY) { - annosvc.setPageAnnotationBinary(aURI, anno.name, anno.value, - anno.value.length, anno.mimeType, - flags, expires); - } - else - annosvc.setPageAnnotation(aURI, anno.name, anno.value, flags, expires); - }); - }, - - /** - * Annotate an item with a batch of annotations. - * @param aItemId - * The identifier of the item for which annotations are to be set - * @param aAnnotations - * Array of objects, each containing the following properties: - * name, flags, expires, type, mimeType (only used for binary - * annotations) value. - */ - setAnnotationsForItem: function PU_setAnnotationsForItem(aItemId, aAnnos) { - var annosvc = this.annotations; - aAnnos.forEach(function(anno) { - var flags = ("flags" in anno) ? anno.flags : 0; - var expires = ("expires" in anno) ? - anno.expires : Ci.nsIAnnotationService.EXPIRE_NEVER; - if (anno.type == annosvc.TYPE_BINARY) { - annosvc.setItemAnnotationBinary(aItemId, anno.name, anno.value, - anno.value.length, anno.mimeType, - flags, expires); - } - else { - annosvc.setItemAnnotation(aItemId, anno.name, anno.value, flags, - expires); - } - }); - }, - - /** - * Helper for getting a serialized Places query for a particular folder. - * @param aFolderId The folder id to get a query for. - * @return string serialized place URI - */ - getQueryStringForFolder: function PU_getQueryStringForFolder(aFolderId) { - var options = this.history.getNewQueryOptions(); - var query = this.history.getNewQuery(); - query.setFolders([aFolderId], 1); - return this.history.queriesToQueryString([query], 1, options); - }, - /** * Get the description associated with a document, as specified in a * element. @@ -1499,85 +813,6 @@ var PlacesUtils = { return ""; }, - // identifier getters for special folders - get placesRootId() { - delete this.placesRootId; - return this.placesRootId = this.bookmarks.placesRoot; - }, - - get bookmarksMenuFolderId() { - delete this.bookmarksMenuFolderId; - return this.bookmarksMenuFolderId = this.bookmarks.bookmarksMenuFolder; - }, - - get toolbarFolderId() { - delete this.toolbarFolderId; - return this.toolbarFolderId = this.bookmarks.toolbarFolder; - }, - - get tagsFolderId() { - delete this.tagsFolderId; - return this.tagsFolderId = this.bookmarks.tagsFolder; - }, - - get unfiledBookmarksFolderId() { - delete this.unfiledBookmarksFolderId; - return this.unfiledBookmarksFolderId = this.bookmarks.unfiledBookmarksFolder; - }, - - /** - * Set the POST data associated with a bookmark, if any. - * Used by POST keywords. - * @param aBookmarkId - * @returns string of POST data - */ - setPostDataForBookmark: function PU_setPostDataForBookmark(aBookmarkId, aPostData) { - const annos = this.annotations; - if (aPostData) - annos.setItemAnnotation(aBookmarkId, POST_DATA_ANNO, aPostData, - 0, Ci.nsIAnnotationService.EXPIRE_NEVER); - else if (annos.itemHasAnnotation(aBookmarkId, POST_DATA_ANNO)) - annos.removeItemAnnotation(aBookmarkId, POST_DATA_ANNO); - }, - - /** - * Get the POST data associated with a bookmark, if any. - * @param aBookmarkId - * @returns string of POST data if set for aBookmarkId. null otherwise. - */ - getPostDataForBookmark: function PU_getPostDataForBookmark(aBookmarkId) { - const annos = this.annotations; - if (annos.itemHasAnnotation(aBookmarkId, POST_DATA_ANNO)) - return annos.getItemAnnotation(aBookmarkId, POST_DATA_ANNO); - - return null; - }, - - /** - * Get the URI (and any associated POST data) for a given keyword. - * @param aKeyword string keyword - * @returns an array containing a string URL and a string of POST data - */ - getURLAndPostDataForKeyword: function PU_getURLAndPostDataForKeyword(aKeyword) { - var url = null, postdata = null; - try { - var uri = this.bookmarks.getURIForKeyword(aKeyword); - if (uri) { - url = uri.spec; - var bookmarks = this.bookmarks.getBookmarkIdsForURI(uri, {}); - for (let i = 0; i < bookmarks.length; i++) { - var bookmark = bookmarks[i]; - var kw = this.bookmarks.getKeywordForBookmark(bookmark); - if (kw == aKeyword) { - postdata = this.getPostDataForBookmark(bookmark); - break; - } - } - } - } catch(ex) {} - return [url, postdata]; - }, - /** * Retrieve the description of an item * @param aItemId @@ -1586,113 +821,11 @@ var PlacesUtils = { * not set. */ getItemDescription: function PU_getItemDescription(aItemId) { - if (this.annotations.itemHasAnnotation(aItemId, DESCRIPTION_ANNO)) - return this.annotations.getItemAnnotation(aItemId, DESCRIPTION_ANNO); + if (PlacesUtils.annotations.itemHasAnnotation(aItemId, DESCRIPTION_ANNO)) + return PlacesUtils.annotations.getItemAnnotation(aItemId, DESCRIPTION_ANNO); return ""; }, - - /** - * Get all bookmarks for a URL, excluding items under tag or livemark - * containers. - */ - getBookmarksForURI: - function PU_getBookmarksForURI(aURI) { - var bmkIds = this.bookmarks.getBookmarkIdsForURI(aURI, {}); - - // filter the ids list - return bmkIds.filter(function(aID) { - var parent = this.bookmarks.getFolderIdForItem(aID); - // Livemark child - if (this.annotations.itemHasAnnotation(parent, LMANNO_FEEDURI)) - return false; - var grandparent = this.bookmarks.getFolderIdForItem(parent); - // item under a tag container - if (grandparent == this.tagsFolderId) - return false; - return true; - }, this); - }, - - /** - * Get the most recently added/modified bookmark for a URL, excluding items - * under tag or livemark containers. -1 is returned if no item is found. - */ - getMostRecentBookmarkForURI: - function PU_getMostRecentBookmarkForURI(aURI) { - var bmkIds = this.bookmarks.getBookmarkIdsForURI(aURI, {}); - for (var i = 0; i < bmkIds.length; i++) { - // Find the first folder which isn't a tag container - var bk = bmkIds[i]; - var parent = this.bookmarks.getFolderIdForItem(bk); - if (parent == this.unfiledBookmarksFolderId) - return bk; - - var grandparent = this.bookmarks.getFolderIdForItem(parent); - if (grandparent != this.tagsFolderId && - !this.annotations.itemHasAnnotation(parent, LMANNO_FEEDURI)) - return bk; - } - return -1; - }, - - getMostRecentFolderForFeedURI: - function PU_getMostRecentFolderForFeedURI(aURI) { - var feedSpec = aURI.spec - var annosvc = this.annotations; - var livemarks = annosvc.getItemsWithAnnotation(LMANNO_FEEDURI, {}); - for (var i = 0; i < livemarks.length; i++) { - if (annosvc.getItemAnnotation(livemarks[i], LMANNO_FEEDURI) == feedSpec) - return livemarks[i]; - } - return -1; - }, - - getURLsForContainerNode: function PU_getURLsForContainerNode(aNode) { - let urls = []; - if (this.nodeIsFolder(aNode) && asQuery(aNode).queryOptions.excludeItems) { - // grab manually - let contents = this.getFolderContents(aNode.itemId, false, false).root; - for (let i = 0; i < contents.childCount; ++i) { - let child = contents.getChild(i); - if (this.nodeIsURI(child)) - urls.push({uri: child.uri, isBookmark: this.nodeIsBookmark(child)}); - } - } - else { - let result, oldViewer, wasOpen; - try { - let wasOpen = aNode.containerOpen; - result = aNode.parentResult; - oldViewer = result.viewer; - if (!wasOpen) { - result.viewer = null; - aNode.containerOpen = true; - } - for (let i = 0; i < aNode.childCount; ++i) { - // Include visible url nodes only - let child = aNode.getChild(i); - if (this.nodeIsURI(child)) { - // If the node contents is visible, add the uri - if ((wasOpen && oldViewer && child.viewIndex != -1) || - urls.indexOf(child.uri) == -1) { - urls.push({ uri: child.uri, - isBookmark: this.nodeIsBookmark(child) }); - } - } - } - if (!wasOpen) - aNode.containerOpen = false; - } - finally { - if (!wasOpen) - result.viewer = oldViewer; - } - } - - return urls; - }, - /** * Gives the user a chance to cancel loading lots of tabs at once */ @@ -1767,7 +900,7 @@ var PlacesUtils = { }, openContainerNodeInTabs: function PU_openContainerInTabs(aNode, aEvent) { - var urlsToOpen = this.getURLsForContainerNode(aNode); + var urlsToOpen = PlacesUtils.getURLsForContainerNode(aNode); if (!this._confirmOpenInTabs(urlsToOpen.length)) return; @@ -1778,8 +911,8 @@ var PlacesUtils = { var urlsToOpen = []; for (var i=0; i < aNodes.length; i++) { // skip over separators and folders - if (this.nodeIsURI(aNodes[i])) - urlsToOpen.push({uri: aNodes[i].uri, isBookmark: this.nodeIsBookmark(aNodes[i])}); + if (PlacesUtils.nodeIsURI(aNodes[i])) + urlsToOpen.push({uri: aNodes[i].uri, isBookmark: PlacesUtils.nodeIsBookmark(aNodes[i])}); } this._openTabset(urlsToOpen, aEvent); }, @@ -1805,13 +938,13 @@ var PlacesUtils = { */ openNodeIn: function PU_openNodeIn(aNode, aWhere) { if (aNode && PlacesUtils.nodeIsURI(aNode) && - PlacesUtils.checkURLSecurity(aNode)) { + this.checkURLSecurity(aNode)) { var isBookmark = PlacesUtils.nodeIsBookmark(aNode); if (isBookmark) - PlacesUtils.markPageAsFollowedBookmark(aNode.uri); + this.markPageAsFollowedBookmark(aNode.uri); else - PlacesUtils.markPageAsTyped(aNode.uri); + this.markPageAsTyped(aNode.uri); // Check whether the node is a bookmark which should be opened as // a web panel @@ -1843,22 +976,22 @@ var PlacesUtils = { if (iconURI) iconURISpec = iconURI.spec; - if (this.uriTypes.indexOf(type) != -1) { + if (PlacesUtils.uriTypes.indexOf(type) != -1) { element = document.createElement("menuitem"); element.setAttribute("statustext", aNode.uri); element.className = "menuitem-iconic bookmark-item"; } - else if (this.containerTypes.indexOf(type) != -1) { + else if (PlacesUtils.containerTypes.indexOf(type) != -1) { element = document.createElement("menu"); element.setAttribute("container", "true"); if (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY) element.setAttribute("query", "true"); else if (aNode.itemId != -1) { - if (this.nodeIsLivemarkContainer(aNode)) + if (PlacesUtils.nodeIsLivemarkContainer(aNode)) element.setAttribute("livemark", "true"); - else if (this.bookmarks - .getFolderIdForItem(aNode.itemId) == this.tagsFolderId) + else if (PlacesUtils.bookmarks. + getFolderIdForItem(aNode.itemId) == PlacesUtils.tagsFolderId) element.setAttribute("tagContainer", "true"); } @@ -1897,17 +1030,18 @@ var PlacesUtils = { get leftPaneFolderId() { var leftPaneRoot = -1; var allBookmarksId; - var items = this.annotations.getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO, {}); + var items = PlacesUtils.annotations.getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO, {}); if (items.length != 0 && items[0] != -1) leftPaneRoot = items[0]; if (leftPaneRoot != -1) { // Build the leftPaneQueries Map delete this.leftPaneQueries; this.leftPaneQueries = {}; - var items = this.annotations.getItemsWithAnnotation(ORGANIZER_QUERY_ANNO, { }); + var items = PlacesUtils.annotations. + getItemsWithAnnotation(ORGANIZER_QUERY_ANNO, { }); for (var i=0; i < items.length; i++) { - var queryName = this.annotations - .getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO); + var queryName = PlacesUtils.annotations. + getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO); this.leftPaneQueries[queryName] = items[i]; } delete this.leftPaneFolderId; @@ -1915,69 +1049,70 @@ var PlacesUtils = { } var self = this; - const EXPIRE_NEVER = this.annotations.EXPIRE_NEVER; + const EXPIRE_NEVER = PlacesUtils.annotations.EXPIRE_NEVER; var callback = { runBatched: function(aUserData) { delete self.leftPaneQueries; self.leftPaneQueries = { }; // Left Pane Root Folder - leftPaneRoot = self.bookmarks.createFolder(self.placesRootId, "", -1); + leftPaneRoot = + PlacesUtils.bookmarks.createFolder(PlacesUtils.placesRootId, "", -1); // History Query - let uri = self._uri("place:sort=4&"); + let uri = PlacesUtils._uri("place:sort=4&"); let title = self.getString("OrganizerQueryHistory"); - let itemId = self.bookmarks.insertBookmark(leftPaneRoot, uri, -1, title); - self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, - "History", 0, EXPIRE_NEVER); + let itemId = PlacesUtils.bookmarks.insertBookmark(leftPaneRoot, uri, -1, title); + PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, + "History", 0, EXPIRE_NEVER); self.leftPaneQueries["History"] = itemId; // XXX: Downloads // Tags Query - uri = self._uri("place:folder=" + self.tagsFolderId); - itemId = self.bookmarks.insertBookmark(leftPaneRoot, uri, -1, null); - self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, - "Tags", 0, EXPIRE_NEVER); + uri = PlacesUtils._uri("place:folder=" + PlacesUtils.tagsFolderId); + itemId = PlacesUtils.bookmarks.insertBookmark(leftPaneRoot, uri, -1, null); + PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, + "Tags", 0, EXPIRE_NEVER); self.leftPaneQueries["Tags"] = itemId; // All Bookmarks Folder title = self.getString("OrganizerQueryAllBookmarks"); - itemId = self.bookmarks.createFolder(leftPaneRoot, title, -1); + itemId = PlacesUtils.bookmarks.createFolder(leftPaneRoot, title, -1); allBookmarksId = itemId; - self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, - "AllBookmarks", 0, EXPIRE_NEVER); + PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, + "AllBookmarks", 0, EXPIRE_NEVER); self.leftPaneQueries["AllBookmarks"] = itemId; // All Bookmarks->Bookmarks Toolbar Query - uri = self._uri("place:folder=" + self.toolbarFolderId); - itemId = self.bookmarks.insertBookmark(allBookmarksId, uri, -1, null); - self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, - "BookmarksToolbar", 0, EXPIRE_NEVER); + uri = PlacesUtils._uri("place:folder=" + PlacesUtils.toolbarFolderId); + itemId = PlacesUtils.bookmarks.insertBookmark(allBookmarksId, uri, -1, null); + PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, + "BookmarksToolbar", 0, EXPIRE_NEVER); self.leftPaneQueries["BookmarksToolbar"] = itemId; // All Bookmarks->Bookmarks Menu Query - uri = self._uri("place:folder=" + self.bookmarksMenuFolderId); - itemId = self.bookmarks.insertBookmark(allBookmarksId, uri, -1, null); - self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, - "BookmarksMenu", 0, EXPIRE_NEVER); + uri = PlacesUtils._uri("place:folder=" + PlacesUtils.bookmarksMenuFolderId); + itemId = PlacesUtils.bookmarks.insertBookmark(allBookmarksId, uri, -1, null); + PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, + "BookmarksMenu", 0, EXPIRE_NEVER); self.leftPaneQueries["BookmarksMenu"] = itemId; // All Bookmarks->Unfiled bookmarks - uri = self._uri("place:folder=" + self.unfiledBookmarksFolderId); - itemId = self.bookmarks.insertBookmark(allBookmarksId, uri, -1, null); - self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, - "UnfiledBookmarks", 0, - EXPIRE_NEVER); + uri = PlacesUtils._uri("place:folder=" + PlacesUtils.unfiledBookmarksFolderId); + itemId = PlacesUtils.bookmarks.insertBookmark(allBookmarksId, uri, -1, null); + PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, + "UnfiledBookmarks", 0, + EXPIRE_NEVER); self.leftPaneQueries["UnfiledBookmarks"] = itemId; // disallow manipulating this folder within the organizer UI - self.bookmarks.setFolderReadonly(leftPaneRoot, true); + PlacesUtils.bookmarks.setFolderReadonly(leftPaneRoot, true); } }; - this.bookmarks.runInBatchMode(callback, null); - this.annotations.setItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO, - true, 0, EXPIRE_NEVER); + PlacesUtils.bookmarks.runInBatchMode(callback, null); + PlacesUtils.annotations.setItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO, + true, 0, EXPIRE_NEVER); delete this.leftPaneFolderId; return this.leftPaneFolderId = leftPaneRoot; }, @@ -1990,12 +1125,12 @@ var PlacesUtils = { } }; -PlacesUtils.placesFlavors = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, - PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, - PlacesUtils.TYPE_X_MOZ_PLACE]; +PlacesUIUtils.placesFlavors = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, + PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, + PlacesUtils.TYPE_X_MOZ_PLACE]; -PlacesUtils.GENERIC_VIEW_DROP_TYPES = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, - PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, - PlacesUtils.TYPE_X_MOZ_PLACE, - PlacesUtils.TYPE_X_MOZ_URL, - PlacesUtils.TYPE_UNICODE]; +PlacesUIUtils.GENERIC_VIEW_DROP_TYPES = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, + PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, + PlacesUtils.TYPE_X_MOZ_PLACE, + PlacesUtils.TYPE_X_MOZ_URL, + PlacesUtils.TYPE_UNICODE]; diff --git a/browser/components/places/src/Makefile.in b/browser/components/places/src/Makefile.in index a30e6ffecec..e1b30a90ce7 100644 --- a/browser/components/places/src/Makefile.in +++ b/browser/components/places/src/Makefile.in @@ -67,6 +67,8 @@ CPPSRCS = nsPlacesImportExportService.cpp EXTRA_COMPONENTS = nsPlacesTransactionsService.js +EXTRA_PP_COMPONENTS = nsPlacesTransactionsService.js + include $(topsrcdir)/config/rules.mk XPIDL_FLAGS += -I$(topsrcdir)/browser/components diff --git a/browser/components/places/src/nsPlacesImportExportService.cpp b/browser/components/places/src/nsPlacesImportExportService.cpp index 9025bf5d9db..8b7508ffe33 100644 --- a/browser/components/places/src/nsPlacesImportExportService.cpp +++ b/browser/components/places/src/nsPlacesImportExportService.cpp @@ -381,10 +381,10 @@ protected: // importing bookmarks.html files. PRBool mAllowRootChanges; - // if set, this is an import of initial bookmarks.html content, + // If set, this is an import of initial bookmarks.html content, // so we don't want to kick off HTTP traffic // and we want the imported personal toolbar folder - // to be set as the personal toolbar folder. (if not set + // to be set as the personal toolbar folder. (If not set // we will treat it as a normal folder.) PRBool mIsImportDefaults; @@ -2440,9 +2440,7 @@ nsPlacesImportExportService::ExportHTMLToFile(nsILocalFile* aBookmarksFile) return rv; } -#define BROWSER_BOOKMARKS_OVERWRITE_PREF "browser.bookmarks.overwrite" #define BROWSER_BOOKMARKS_MAX_BACKUPS_PREF "browser.bookmarks.max_backups" -#define POSTPLACES_BOOKMARKS_FILE "bookmarks.postplaces.html" NS_IMETHODIMP nsPlacesImportExportService::BackupBookmarksFile() @@ -2458,15 +2456,6 @@ nsPlacesImportExportService::BackupBookmarksFile() rv = NS_GetSpecialDirectory(NS_APP_BOOKMARKS_50_FILE, getter_AddRefs(bookmarksFileDir)); - PRBool overwriteBookmarks; - rv = prefs->GetBoolPref(BROWSER_BOOKMARKS_OVERWRITE_PREF, &overwriteBookmarks); - NS_ENSURE_SUCCESS(rv, rv); - - if (!overwriteBookmarks) { - rv = bookmarksFileDir->SetLeafName(NS_LITERAL_STRING(POSTPLACES_BOOKMARKS_FILE)); - NS_ENSURE_SUCCESS(rv, rv); - } - NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr bookmarksFile(do_QueryInterface(bookmarksFileDir)); @@ -2483,17 +2472,6 @@ nsPlacesImportExportService::BackupBookmarksFile() rv = ExportHTMLToFile(bookmarksFile); NS_ENSURE_SUCCESS(rv, rv); - // archive if needed - PRInt32 numberOfBackups; - rv = prefs->GetIntPref(BROWSER_BOOKMARKS_MAX_BACKUPS_PREF, &numberOfBackups); - if (NS_FAILED(rv)) - numberOfBackups = 5; - - if (numberOfBackups > 0) { - rv = ArchiveBookmarksFile(numberOfBackups, PR_FALSE); - NS_ENSURE_SUCCESS(rv, rv); - } - return NS_OK; } @@ -2509,7 +2487,7 @@ nsPlacesImportExportService::BackupBookmarksFile() */ nsresult nsPlacesImportExportService::ArchiveBookmarksFile(PRInt32 numberOfBackups, - PRBool forceArchive) + PRBool forceArchive) { nsCOMPtr bookmarksBackupDir; nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, @@ -2530,7 +2508,7 @@ nsPlacesImportExportService::ArchiveBookmarksFile(PRInt32 numberOfBackups, } // construct the new leafname - PRTime now64 = PR_Now(); + PRTime now64 = PR_Now(); PRExplodedTime nowInfo; PR_ExplodeTime(now64, PR_LocalTimeParameters, &nowInfo); PR_NormalizeTime(&nowInfo, PR_LocalTimeParameters); @@ -2541,8 +2519,6 @@ nsPlacesImportExportService::ArchiveBookmarksFile(PRInt32 numberOfBackups, // and makes the alphabetical order of multiple backup files more useful. PR_FormatTime(timeString, 128, "bookmarks-%Y-%m-%d.html", &nowInfo); - //nsCAutoString backupFilenameCString(timeString); - //nsAutoString backupFilenameString = NS_ConvertUTF8toUTF16(backupFilenameCString); nsAutoString backupFilenameString = NS_ConvertUTF8toUTF16((timeString)); nsCOMPtr backupFile; @@ -2609,18 +2585,6 @@ nsPlacesImportExportService::ArchiveBookmarksFile(PRInt32 numberOfBackups, getter_AddRefs(bookmarksFile)); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - - PRBool overwriteBookmarks; - rv = prefs->GetBoolPref(BROWSER_BOOKMARKS_OVERWRITE_PREF, &overwriteBookmarks); - NS_ENSURE_SUCCESS(rv, rv); - - if (!overwriteBookmarks) { - rv = bookmarksFile->SetLeafName(NS_LITERAL_STRING(POSTPLACES_BOOKMARKS_FILE)); - NS_ENSURE_SUCCESS(rv, rv); - } - rv = bookmarksFile->CopyTo(bookmarksBackupDir, backupFilenameString); // at least dump something out in case this fails in a debug build NS_ENSURE_SUCCESS(rv, rv); diff --git a/browser/components/places/src/nsPlacesTransactionsService.js b/browser/components/places/src/nsPlacesTransactionsService.js index 5601e2db2aa..a82ac415679 100644 --- a/browser/components/places/src/nsPlacesTransactionsService.js +++ b/browser/components/places/src/nsPlacesTransactionsService.js @@ -37,16 +37,15 @@ * * ***** END LICENSE BLOCK ***** */ +let Ci = Components.interfaces; +let Cc = Components.classes; +let Cr = Components.results; + const loadInSidebarAnno = "bookmarkProperties/loadInSidebar"; const descriptionAnno = "bookmarkProperties/description"; const CLASS_ID = Components.ID("c0844a84-5a12-4808-80a8-809cb002bb4f"); const CONTRACT_ID = "@mozilla.org/browser/placesTransactionsService;1"; -var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]. - getService(Components.interfaces.mozIJSSubScriptLoader); -loader.loadSubScript("chrome://global/content/debug.js"); -loader.loadSubScript("chrome://browser/content/places/utils.js"); - Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); // The minimum amount of transactions we should tell our observers to begin @@ -56,6 +55,7 @@ const MIN_TRANSACTIONS_FOR_BATCH = 5; function placesTransactionsService() { this.mTransactionManager = Cc["@mozilla.org/transactionmanager;1"]. createInstance(Ci.nsITransactionManager); + Components.utils.import("resource://gre/modules/utils.js"); } placesTransactionsService.prototype = { @@ -442,6 +442,7 @@ placesCreateLivemarkTransactions.prototype = { }; function placesMoveItemTransactions(aItemId, aNewContainer, aNewIndex) { + Components.utils.import("resource://gre/modules/debug.js"); NS_ASSERT(aNewIndex >= -1, "invalid insertion index"); this._id = aItemId; this._oldContainer = PlacesUtils.bookmarks.getFolderIdForItem(this._id); diff --git a/browser/components/places/tests/unit/head_bookmarks.js b/browser/components/places/tests/unit/head_bookmarks.js index df5fcd80906..e087eac6e9c 100644 --- a/browser/components/places/tests/unit/head_bookmarks.js +++ b/browser/components/places/tests/unit/head_bookmarks.js @@ -37,6 +37,8 @@ * * ***** END LICENSE BLOCK ***** */ +version(170); + const NS_APP_USER_PROFILE_50_DIR = "ProfD"; var Ci = Components.interfaces; var Cc = Components.classes; diff --git a/browser/components/places/tests/unit/test_384370.js b/browser/components/places/tests/unit/test_384370.js index a1592eea0c0..7c8cddd38d2 100644 --- a/browser/components/places/tests/unit/test_384370.js +++ b/browser/components/places/tests/unit/test_384370.js @@ -36,7 +36,286 @@ * * ***** END LICENSE BLOCK ***** */ +const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar"; +const DESCRIPTION_ANNO = "bookmarkProperties/description"; +const POST_DATA_ANNO = "bookmarkProperties/POSTData"; +const LAST_CHARSET_ANNO = "URIProperties/characterSet"; + +Components.utils.import("resource://gre/modules/utils.js"); +do_check_eq(typeof PlacesUtils, "object"); + +// main function run_test() { - // XXX test disabled due to backout of bug 384370 - return; + /* + HTML+FEATURES SUMMARY: + - import legacy bookmarks + - export as json, import, test (tests integrity of html > json) + - export as html, import, test (tests integrity of json > html) + + BACKUP/RESTORE SUMMARY: + - create a bookmark in each root + - tag multiple URIs with multiple tags + - export as json, import, test + */ + + // get places import/export service + var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].getService(Ci.nsIPlacesImportExportService); + + // avoid creating the places smart folder during tests + Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch). + setBoolPref("browser.places.createdSmartBookmarks", true); + + // file pointer to legacy bookmarks file + //var bookmarksFileOld = do_get_file("browser/components/places/tests/unit/bookmarks.large.html"); + var bookmarksFileOld = do_get_file("browser/components/places/tests/unit/bookmarks.preplaces.html"); + // file pointer to a new places-exported json file + var jsonFile = dirSvc.get("ProfD", Ci.nsILocalFile); + jsonFile.append("bookmarks.exported.json"); + + // create bookmarks.exported.json + if (jsonFile.exists()) + jsonFile.remove(false); + jsonFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0600); + if (!jsonFile.exists()) + do_throw("couldn't create file: bookmarks.exported.json"); + + // Test importing a pre-Places canonical bookmarks file. + // 1. import bookmarks.preplaces.html + // 2. run the test-suite + // Note: we do not empty the db before this import to catch bugs like 380999 + try { + importer.importHTMLFromFile(bookmarksFileOld, true); + } catch(ex) { do_throw("couldn't import legacy bookmarks file: " + ex); } + populate(); + validate(); + + // Test exporting a Places canonical json file. + // 1. export to bookmarks.exported.json + // 2. empty bookmarks db + // 3. import bookmarks.exported.json + // 4. run the test-suite + try { + PlacesUtils.backupBookmarksToFile(jsonFile); + } catch(ex) { do_throw("couldn't export to file: " + ex); } + LOG("exported json"); + try { + PlacesUtils.restoreBookmarksFromFile(jsonFile); + } catch(ex) { do_throw("couldn't import the exported file: " + ex); } + LOG("imported json"); + validate(); + LOG("validated import"); +} + +var tagData = [ + { uri: uri("http://slint.us"), tags: ["indie", "kentucky", "music"] }, + { uri: uri("http://en.wikipedia.org/wiki/Diplodocus"), tags: ["dinosaur", "dj", "rad word"] } +]; + +var recentTagsQueryURI = uri("place:folder=" + PlacesUtils.bookmarks.tagsFolder + + "&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER + + "&applyOptionsToContainers=1" + + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS); + +var bookmarkData = [ + //{ uri: uri("http://www.saveur.com/"), title: "Saveur Magazine" }, + //{ uri: uri("http://twitter.com/"), title: "Twitter" }, + { uri: uri("http://slint.us"), title: "indie, kentucky, music" }, + { uri: uri("http://en.wikipedia.org/wiki/Diplodocus"), title: "dinosaur, dj, rad word" } + //{ uri: recentTagsQueryURI, title: "Recent Tags" } +]; + +/* +populate data in each folder +(menu is populated via the html import) +*/ +function populate() { + // add tags + for each(let {uri: u, tags: t} in tagData) + PlacesUtils.tagging.tagURI(u, t); + + // add unfiled bookmarks + for each(let {uri: u, title: t} in bookmarkData) { + PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.unfiledBookmarksFolder, + u, PlacesUtils.bookmarks.DEFAULT_INDEX, t); + } + + // add to the toolbar + for each(let {uri: u, title: t} in bookmarkData) { + PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.toolbarFolder, + u, PlacesUtils.bookmarks.DEFAULT_INDEX, t); + } +} + +function validate() { + testCanonicalBookmarks(PlacesUtils.bookmarks.bookmarksMenuFolder); + testToolbarFolder(); + testUnfiledBookmarks(); + testTags(); +} + +// Tests a bookmarks datastore that has a set of bookmarks, etc +// that flex each supported field and feature. +function testCanonicalBookmarks() { + // query to see if the deleted folder and items have been imported + var query = PlacesUtils.history.getNewQuery(); + query.setFolders([PlacesUtils.bookmarks.bookmarksMenuFolder], 1); + var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions()); + var rootNode = result.root; + rootNode.containerOpen = true; + + // 6-2: the toolbar contents are imported to the places-toolbar folder, + // the separator above it is removed. + do_check_eq(rootNode.childCount, 4); + + // get test folder + var testFolder = rootNode.getChild(3); + do_check_eq(testFolder.type, testFolder.RESULT_TYPE_FOLDER); + do_check_eq(testFolder.title, "test"); + + /* + // add date + do_check_eq(PlacesUtils.bookmarks.getItemDateAdded(testFolder.itemId)/1000000, 1177541020); + // last modified + do_check_eq(PlacesUtils.bookmarks.getItemLastModified(testFolder.itemId)/1000000, 1177541050); + */ + + testFolder = testFolder.QueryInterface(Ci.nsINavHistoryQueryResultNode); + do_check_eq(testFolder.hasChildren, true); + // folder description + do_check_true(PlacesUtils.annotations.itemHasAnnotation(testFolder.itemId, + DESCRIPTION_ANNO)); + do_check_eq("folder test comment", + PlacesUtils.annotations.getItemAnnotation(testFolder.itemId, DESCRIPTION_ANNO)); + // open test folder, and test the children + testFolder.containerOpen = true; + var cc = testFolder.childCount; + // XXX Bug 380468 + // do_check_eq(cc, 2); + do_check_eq(cc, 1); + + // test bookmark 1 + var testBookmark1 = testFolder.getChild(0); + // url + do_check_eq("http://test/post", testBookmark1.uri); + // title + do_check_eq("test post keyword", testBookmark1.title); + // keyword + do_check_eq("test", PlacesUtils.bookmarks.getKeywordForBookmark(testBookmark1.itemId)); + // sidebar + do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId, + LOAD_IN_SIDEBAR_ANNO)); + /* + // add date + do_check_eq(testBookmark1.dateAdded/1000000, 1177375336); + + // last modified + do_check_eq(testBookmark1.lastModified/1000000, 1177375423); + */ + + // post data + do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId, POST_DATA_ANNO)); + do_check_eq("hidden1%3Dbar&text1%3D%25s", + PlacesUtils.annotations.getItemAnnotation(testBookmark1.itemId, POST_DATA_ANNO)); + + // last charset + do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId, LAST_CHARSET_ANNO)); + do_check_eq("ISO-8859-1", PlacesUtils.annotations.getItemAnnotation(testBookmark1.itemId, + LAST_CHARSET_ANNO)); + // description + do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId, + DESCRIPTION_ANNO)); + do_check_eq("item description", + PlacesUtils.annotations.getItemAnnotation(testBookmark1.itemId, + DESCRIPTION_ANNO)); + + /* + // XXX Bug 380468 + // test bookmark 2 + var testBookmark2 = testFolder.getChild(1); + // url + do_check_eq("http://test/micsum", testBookmark2.uri); + // title + do_check_eq("test microsummary", testBookmark2.title); + // check that it's a microsummary + var micsum = mssvc.getMicrosummary(testBookmark2.itemId); + if (!micsum) + do_throw("Could not import microsummary"); + // check generator uri + var generator = micsum.generator; + do_check_eq("urn:source:http://dietrich.ganx4.com/mozilla/test-microsummary.xml", generator.uri.spec); + // expiration and generated title can change, so don't test them + */ + + // clean up + testFolder.containerOpen = false; + rootNode.containerOpen = false; +} + +function testToolbarFolder() { + var query = PlacesUtils.history.getNewQuery(); + query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1); + var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions()); + + var toolbar = result.root; + toolbar.containerOpen = true; + + // child count (add 2 for pre-existing items) + do_check_eq(toolbar.childCount, bookmarkData.length + 2); + + // livemark + var livemark = toolbar.getChild(1); + // title + do_check_eq("Latest Headlines", livemark.title); + // livemark check + do_check_true(PlacesUtils.livemarks.isLivemark(livemark.itemId)); + // site url + do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/", + PlacesUtils.livemarks.getSiteURI(livemark.itemId).spec); + // feed url + do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml", + PlacesUtils.livemarks.getFeedURI(livemark.itemId).spec); + + // test added bookmark data + var child = toolbar.getChild(2); + do_check_eq(child.uri, bookmarkData[0].uri.spec); + do_check_eq(child.title, bookmarkData[0].title); + child = toolbar.getChild(3); + do_check_eq(child.uri, bookmarkData[1].uri.spec); + do_check_eq(child.title, bookmarkData[1].title); + + toolbar.containerOpen = false; +} + +function testUnfiledBookmarks() { + var query = PlacesUtils.history.getNewQuery(); + query.setFolders([PlacesUtils.bookmarks.unfiledBookmarksFolder], 1); + var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions()); + var rootNode = result.root; + rootNode.containerOpen = true; + do_check_eq(rootNode.childCount, bookmarkData.length); + for (var i = 0; i < rootNode.childCount; i++) { + var child = rootNode.getChild(i); + dump(bookmarkData[i].uri.spec + " == " + child.uri + "?\n"); + do_check_true(bookmarkData[i].uri.equals(uri(child.uri))); + do_check_eq(child.title, bookmarkData[i].title); + /* WTF + if (child.tags) + do_check_eq(child.tags, bookmarkData[i].title); + */ + } + rootNode.containerOpen = false; +} + +function testTags() { + for each(let {uri: u, tags: t} in tagData) { + var i = 0; + dump("test tags for " + u.spec + ": " + t + "\n"); + var tt = PlacesUtils.tagging.getTagsForURI(u, {}); + dump("true tags for " + u.spec + ": " + tt + "\n"); + do_check_true(t.every(function(el) { + i++; + return tt.indexOf(el) > -1; + })); + do_check_eq(i, t.length); + } } diff --git a/browser/components/places/tests/unit/test_398914.js b/browser/components/places/tests/unit/test_398914.js index 37187e1d339..5c8b39e084c 100644 --- a/browser/components/places/tests/unit/test_398914.js +++ b/browser/components/places/tests/unit/test_398914.js @@ -36,12 +36,7 @@ * * ***** END LICENSE BLOCK ***** */ -version(170); - -var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]. - getService(Ci.mozIJSSubScriptLoader); -loader.loadSubScript("chrome://global/content/debug.js"); -loader.loadSubScript("chrome://browser/content/places/utils.js"); +Components.utils.import("resource://gre/modules/utils.js"); const bmsvc = PlacesUtils.bookmarks; const testFolderId = PlacesUtils.bookmarksMenuFolderId; diff --git a/browser/components/places/tests/unit/test_bookmarks_html.js b/browser/components/places/tests/unit/test_bookmarks_html.js index 04fcfbf7aa8..f7ef1f1e9b1 100644 --- a/browser/components/places/tests/unit/test_bookmarks_html.js +++ b/browser/components/places/tests/unit/test_bookmarks_html.js @@ -78,7 +78,6 @@ try { do_throw("Could not get io service\n"); } - const DESCRIPTION_ANNO = "bookmarkProperties/description"; const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar"; const POST_DATA_ANNO = "bookmarkProperties/POSTData"; diff --git a/browser/components/sidebar/src/nsSidebar.js b/browser/components/sidebar/src/nsSidebar.js index 991960514ef..159b4d94e39 100644 --- a/browser/components/sidebar/src/nsSidebar.js +++ b/browser/components/sidebar/src/nsSidebar.js @@ -129,7 +129,7 @@ function (aTitle, aContentURL, aCustomizeURL, aPersist) } catch(ex) { return; } - win.PlacesUtils.showMinimalAddBookmarkUI(uri, aTitle, null, null, true, true); + win.PlacesUIUtils.showMinimalAddBookmarkUI(uri, aTitle, null, null, true, true); } nsSidebar.prototype.validateSearchEngine = diff --git a/toolkit/components/places/src/Makefile.in b/toolkit/components/places/src/Makefile.in index 3186ba41b9a..6ddcc4d663b 100644 --- a/toolkit/components/places/src/Makefile.in +++ b/toolkit/components/places/src/Makefile.in @@ -105,4 +105,8 @@ EXTRA_PP_COMPONENTS = nsLivemarkService.js \ nsTaggingService.js \ $(NULL) +EXTRA_JS_MODULES = utils.js + +EXTRA_PP_JS_MODULES = utils.js + include $(topsrcdir)/config/rules.mk diff --git a/toolkit/components/places/src/nsTaggingService.js b/toolkit/components/places/src/nsTaggingService.js index 0426a933d6f..d1deaa4016d 100644 --- a/toolkit/components/places/src/nsTaggingService.js +++ b/toolkit/components/places/src/nsTaggingService.js @@ -194,13 +194,14 @@ TaggingService.prototype = { * the item-id of the tag element under the tags root */ _removeTagIfEmpty: function TS__removeTagIfEmpty(aTagId) { - var options = this._history.getNewQueryOptions(); - var query = this._history.getNewQuery(); - query.setFolders([aTagId], 1); - var result = this._history.executeQuery(query, options); - var rootNode = result.root; - rootNode.containerOpen = true; - if (rootNode.childCount == 0) + var node = this._getTagNode(aTagId).QueryInterface(Ci.nsINavHistoryContainerResultNode); + var wasOpen = node.containerOpen; + if (!wasOpen) + node.containerOpen = true; + var cc = node.childCount; + if (wasOpen) + node.containerOpen = false; + if (cc == 0) this._bms.removeFolder(aTagId); },