From a15fbe37508762d08449a2503221ceecb851cebd Mon Sep 17 00:00:00 2001 From: "dietrich@mozilla.com" Date: Wed, 27 Feb 2008 11:05:52 -0800 Subject: [PATCH] backing out bug 384370, caused 25ms Ts regression on linux, and leaks on linux and mac --- browser/app/profile/firefox.js | 7 +- browser/base/content/browser-menubar.inc | 2 +- browser/base/content/browser-places.js | 58 +- browser/base/content/browser.js | 16 +- browser/base/content/nsContextMenu.js | 6 +- browser/components/nsBrowserGlue.js | 139 +- .../places/content/bookmarkProperties.js | 76 +- .../places/content/bookmarksPanel.js | 2 +- .../components/places/content/controller.js | 91 +- .../places/content/editBookmarkOverlay.js | 68 +- .../places/content/history-panel.js | 2 +- browser/components/places/content/menu.xml | 6 +- .../places/content/moveBookmarks.js | 8 +- browser/components/places/content/places.js | 140 +- browser/components/places/content/places.xul | 2 +- .../places/content/placesOverlay.xul | 6 +- .../components/places/content/sidebarUtils.js | 4 +- browser/components/places/content/toolbar.xml | 6 +- browser/components/places/content/tree.xml | 2 +- browser/components/places/content/treeView.js | 20 +- browser/components/places/content/utils.js | 1188 ++++++++++++++--- browser/components/places/src/Makefile.in | 2 - .../src/nsPlacesImportExportService.cpp | 44 +- .../places/src/nsPlacesTransactionsService.js | 11 +- .../places/tests/unit/head_bookmarks.js | 2 - .../places/tests/unit/test_398914.js | 7 +- .../places/tests/unit/test_bookmarks_html.js | 1 + browser/components/sidebar/src/nsSidebar.js | 2 +- toolkit/components/places/src/Makefile.in | 4 - .../components/places/src/nsTaggingService.js | 15 +- toolkit/content/Makefile.in | 3 - toolkit/content/debug.js | 2 - toolkit/content/globalOverlay.js | 2 +- toolkit/content/jar.mn | 1 + 34 files changed, 1389 insertions(+), 556 deletions(-) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 3dc2e7ccd3b..0edbf931bde 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -320,10 +320,9 @@ 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 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); +// By default, do not overwrite bookmarks.html in the profile directory +// See bug #381216 for details +pref("browser.bookmarks.overwrite", 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 c158f8ef004..7bb5910f1cd 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 05751eb840c..304c2e8a3fb 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) { - PlacesUIUtils.ptm.endBatch(); + PlacesUtils.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. - PlacesUIUtils.ptm.doTransaction({ doTransaction: function() { }, - undoTransaction: function() { }, - redoTransaction: function() { }, - isTransient: false, - merge: function() { return false; } }); + PlacesUtils.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(); - PlacesUIUtils.ptm.undoTransaction(); + PlacesUtils.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) { - PlacesUIUtils.ptm.endBatch(); - PlacesUIUtils.ptm.beginBatch(); // allow undo from within the notification + PlacesUtils.ptm.endBatch(); + PlacesUtils.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 = PlacesUIUtils.ptm.removeItem(itemIds[i]); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.removeItem(itemIds[i]); + PlacesUtils.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(); - PlacesUIUtils.ptm.undoTransaction(); + PlacesUtils.ptm.undoTransaction(); this._itemId = PlacesUtils.getMostRecentBookmarkForURI(this._uri); this.showEditBookmarkPopup(); }, beginBatch: function SU_beginBatch() { if (!this._batching) { - PlacesUIUtils.ptm.beginBatch(); + PlacesUtils.ptm.beginBatch(); this._batching = true; } }, endBatch: function SU_endBatch() { if (this._batching) { - PlacesUIUtils.ptm.endBatch(); + PlacesUtils.ptm.endBatch(); this._batching = false; } } @@ -372,7 +372,7 @@ var PlacesCommandHook = { var description; try { title = webNav.document.title || url.spec; - description = PlacesUIUtils.getDescriptionFromDocument(webNav.document); + description = PlacesUtils.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 = PlacesUIUtils.ptm.createItem(uri, parent, -1, - title, null, [descAnno]); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.createItem(uri, parent, -1, + title, null, [descAnno]); + PlacesUtils.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 = PlacesUIUtils.ptm.createItem(linkURI, aParent, -1, aTitle); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.createItem(linkURI, aParent, -1, aTitle); + PlacesUtils.ptm.doTransaction(txn); itemId = PlacesUtils.getMostRecentBookmarkForURI(linkURI); } @@ -474,7 +474,7 @@ var PlacesCommandHook = { */ bookmarkCurrentPages: function PCH_bookmarkCurrentPages() { var tabURIs = this._getUniqueTabInfo(); - PlacesUIUtils.showMinimalAddMultiBookmarkUI(tabURIs); + PlacesUtils.showMinimalAddMultiBookmarkUI(tabURIs); }, @@ -500,12 +500,12 @@ var PlacesCommandHook = { if (arguments.length > 2) description = feedSubtitle; else - description = PlacesUIUtils.getDescriptionFromDocument(doc); + description = PlacesUtils.getDescriptionFromDocument(doc); var toolbarIP = new InsertionPoint(PlacesUtils.bookmarks.toolbarFolder, -1); - PlacesUIUtils.showMinimalAddLivemarkUI(feedURI, gBrowser.currentURI, - title, description, toolbarIP, true); + PlacesUtils.showMinimalAddLivemarkUI(feedURI, gBrowser.currentURI, + title, description, toolbarIP, true); }, /** @@ -581,7 +581,7 @@ var BookmarksEventHandler = { return; var target = aEvent.originalTarget; - var view = PlacesUIUtils.getViewForNode(target); + var view = PlacesUtils.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) - PlacesUIUtils.openNodeWithEvent(target.node, aEvent); + PlacesUtils.openNodeWithEvent(target.node, aEvent); }, /** @@ -685,7 +685,7 @@ var BookmarksEventHandler = { openHomePage.setAttribute("onclick", "checkForMiddleClick(this, event); event.stopPropagation();"); openHomePage.setAttribute("label", - PlacesUIUtils.getFormattedString("menuOpenLivemarkOrigin.label", + PlacesUtils.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", - "PlacesUIUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);"); + "PlacesUtils.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 = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES + var types = PlacesUtils.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 68a6b8dcf11..b528038459e 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -2543,7 +2543,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 - PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(url), split[1]); + PlacesUtils.showMinimalAddBookmarkUI(makeURI(url), split[1]); }, onDragOver: function (aEvent, aFlavour, aDragSession) @@ -3013,7 +3013,7 @@ function addToUrlbarHistory(aUrlToAdd) try { if (aUrlToAdd.indexOf(" ") == -1) { - PlacesUIUtils.markPageAsTyped(aUrlToAdd); + PlacesUtils.markPageAsTyped(aUrlToAdd); } } catch(ex) { @@ -4424,9 +4424,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. - PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(wrapper.href), - wrapper.getAttribute("title"), - null, null, true, true); + PlacesUtils.showMinimalAddBookmarkUI(makeURI(wrapper.href), + wrapper.getAttribute("title"), + null, null, true, true); event.preventDefault(); return false; } @@ -5390,9 +5390,9 @@ function AddKeywordForSearchField() else spec += "?" + formData.join("&"); - var description = PlacesUIUtils.getDescriptionFromDocument(node.ownerDocument); - PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(spec), "", description, null, - null, null, "", postData); + var description = PlacesUtils.getDescriptionFromDocument(node.ownerDocument); + PlacesUtils.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 b08b46fdc58..bd82882c613 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 = PlacesUIUtils.getDescriptionFromDocument(doc); + var description = PlacesUtils.getDescriptionFromDocument(doc); var descAnno = { name: DESCRIPTION_ANNO, value: description }; - var txn = PlacesUIUtils.ptm.createItem(uri, + var txn = PlacesUtils.ptm.createItem(uri, PlacesUtils.bookmarksMenuFolderId, -1, title, null, [descAnno]); - PlacesUIUtils.ptm.doTransaction(txn); + PlacesUtils.ptm.doTransaction(txn); itemId = PlacesUtils.getMostRecentBookmarkForURI(uri); StarUI.beginBatch(); } diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index a5ce77a8f64..de1e922c469 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -45,13 +45,6 @@ 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, @@ -110,22 +103,15 @@ BrowserGlue.prototype = { if (this._saveSession) { this._setPrefToSaveSession(); } - this._shutdownPlaces(); 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() { @@ -338,14 +324,6 @@ 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 @@ -358,11 +336,10 @@ 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) {} @@ -370,95 +347,55 @@ 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 { - // get latest backup - Cu.import("resource://gre/modules/utils.js"); - var bookmarksFile = PlacesUtils.getMostRecentBackup(); - if (bookmarksFile && bookmarksFile.leafName.match("\.json$")) { - // restore a JSON backup - PlacesUtils.restoreBookmarksFromJSONFile(bookmarksFile); + 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); } - else { - // if there's no json backup... - // - use bookmarks.postplaces.html if it exists - // - otherwise use bookmarks.html - var dirService = Cc["@mozilla.org/file/directory_service;1"]. - getService(Ci.nsIProperties); - var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile); - - // bookmarks.postplaces.html - const POSTPLACES_BOOKMARKS_FILE = "bookmarks.postplaces.html"; - var bookmarksPostPlacesFile = bookmarksFile.clone(); - bookmarksPostPlacesFile.leafName = POSTPLACES_BOOKMARKS_FILE; - if (bookmarksPostPlacesFile.exists()) - bookmarksFile = bookmarksPostPlacesFile; - - // 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); + // 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"); + } } } } - - // 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); }, /** * Places shut-down tasks * - back up and archive bookmarks - * - export bookmarks as HTML, if so configured - * - * Note: quit-application-granted notification is received twice - * so replace this method with a no-op when first called. */ _shutdownPlaces: function bg__shutdownPlaces() { - // Backup and archive Places bookmarks. - this._archiveBookmarks(); - - // Backup bookmarks to bookmarks.html to support apps that depend - // on the legacy format. - var autoExportHTML = false; - try { - autoExportHTML = prefs.getIntPref("browser.bookmarks.autoExportHTML"); - } catch(ex) {} - - if (autoExportHTML) { + // backup bookmarks to bookmarks.html + var importer = Cc["@mozilla.org/browser/places/import-export-service;1"]. - getService(Ci.nsIPlacesImportExportService). - backupBookmarksFile(); - } - }, - - /** - * Back up and archive bookmarks - */ - _archiveBookmarks: function nsBrowserGlue__archiveBookmarks() { - Cu.import("resource://gre/modules/utils.js"); - - var lastBackup = PlacesUtils.getMostRecentBackup(); - - // Backup bookmarks if there aren't any backups or - // they haven't been backed up in the last 24 hrs. - if (!lastBackup || - Date.now() - lastBackup.lastModifiedTime > BOOKMARKS_ARCHIVE_INTERVAL) { - var maxBackups = 5; - var prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefBranch); - try { - maxBackups = prefs.getIntPref("browser.bookmarks.max_backups"); - } catch(ex) {} - - PlacesUtils.archiveBookmarksFile(maxBackups, false /* don't force */); - } + getService(Ci.nsIPlacesImportExportService); + importer.backupBookmarksFile(); }, _migrateUI: function bg__migrateUI() { diff --git a/browser/components/places/content/bookmarkProperties.js b/browser/components/places/content/bookmarkProperties.js index 540d67e4c68..a1dd76f4f4c 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 = - PlacesUIUtils.microsummaries.getMicrosummaries(this._bookmarkURI, - this._bookmarkId); + PlacesUtils.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 && - PlacesUIUtils.microsummaries - .isMicrosummary(this._bookmarkId, microsummary)) + PlacesUtils.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 = PlacesUIUtils.createFixedURI(value); + var uri = PlacesUtils.createFixedURI(value); return true; } } catch (e) { } @@ -725,7 +725,7 @@ var BookmarkPropertiesPanel = { */ _getEditTitleTransaction: function BPP__getEditTitleTransaction(aItemId, aNewTitle) { - return PlacesUIUtils.ptm.editItemTitle(aItemId, aNewTitle); + return PlacesUtils.ptm.editItemTitle(aItemId, aNewTitle); }, /** @@ -813,21 +813,21 @@ var BookmarkPropertiesPanel = { // description var description = this._element("descriptionTextfield").value; if (description != this._itemDescription) { - transactions.push(PlacesUIUtils.ptm. + transactions.push(PlacesUtils.ptm. editItemDescription(itemId, description, this._itemType != BOOKMARK_ITEM)); } if (this._itemType == BOOKMARK_ITEM) { // location - var url = PlacesUIUtils.createFixedURI(this._element("editURLBar").value); + var url = PlacesUtils.createFixedURI(this._element("editURLBar").value); if (!this._bookmarkURI.equals(url)) - transactions.push(PlacesUIUtils.ptm.editBookmarkURI(itemId, url)); + transactions.push(PlacesUtils.ptm.editBookmarkURI(itemId, url)); // keyword transactions var newKeyword = this._element("keywordTextfield").value; if (newKeyword != this._bookmarkKeyword) { - transactions.push(PlacesUIUtils.ptm. + transactions.push(PlacesUtils.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 && - PlacesUIUtils.microsummaries.hasMicrosummary(itemId)) || + PlacesUtils.microsummaries.hasMicrosummary(itemId)) || (newMicrosummary != null && - !PlacesUIUtils.microsummaries - .isMicrosummary(itemId, newMicrosummary))) { + !PlacesUtils.microsummaries + .isMicrosummary(itemId, newMicrosummary))) { transactions.push( - PlacesUIUtils.ptm.editBookmarkMicrosummary(itemId, newMicrosummary)); + PlacesUtils.ptm.editBookmarkMicrosummary(itemId, newMicrosummary)); } // load in sidebar var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked; if (loadInSidebarChecked != this._loadBookmarkInSidebar) { transactions.push( - PlacesUIUtils.ptm.setLoadInSidebar(itemId, loadInSidebarChecked)); + PlacesUtils.ptm.setLoadInSidebar(itemId, loadInSidebarChecked)); } } else if (this._itemType == LIVEMARK_CONTAINER) { var feedURIString = this._element("feedLocationTextfield").value; - var feedURI = PlacesUIUtils.createFixedURI(feedURIString); + var feedURI = PlacesUtils.createFixedURI(feedURIString); if (!this._feedURI.equals(feedURI)) { transactions.push( - PlacesUIUtils.ptm.editLivemarkFeedURI(this._folderId, feedURI)); + PlacesUtils.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 = PlacesUIUtils.createFixedURI(newSiteURIString); + newSiteURI = PlacesUtils.createFixedURI(newSiteURIString); if ((!newSiteURI && this._siteURI) || (newSiteURI && (!this._siteURI || !this._siteURI.equals(newSiteURI)))) { transactions.push( - PlacesUIUtils.ptm.editLivemarkSiteURI(this._folderId, newSiteURI)); + PlacesUtils.ptm.editLivemarkSiteURI(this._folderId, newSiteURI)); } } @@ -882,8 +882,8 @@ var BookmarkPropertiesPanel = { if (transactions.length > 0) { window.arguments[0].performed = true; var aggregate = - PlacesUIUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions); - PlacesUIUtils.ptm.doTransaction(aggregate); + PlacesUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions); + PlacesUtils.ptm.doTransaction(aggregate); } }, @@ -912,7 +912,7 @@ var BookmarkPropertiesPanel = { */ _getCreateNewBookmarkTransaction: function BPP__getCreateNewBookmarkTransaction(aContainer, aIndex) { - var uri = PlacesUIUtils.createFixedURI(this._element("editURLBar").value); + var uri = PlacesUtils.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( - PlacesUIUtils.ptm.editBookmarkMicrosummary(-1, microsummary)); + PlacesUtils.ptm.editBookmarkMicrosummary(-1, microsummary)); } if (this._postData) { childTransactions.push( - PlacesUIUtils.ptm.editBookmarkPostData(-1, this._postData)); + PlacesUtils.ptm.editBookmarkPostData(-1, this._postData)); } - var transactions = [PlacesUIUtils.ptm.createItem(uri, aContainer, aIndex, - title, keyword, - annotations, - childTransactions)]; + var transactions = [PlacesUtils.ptm.createItem(uri, aContainer, aIndex, + title, keyword, + annotations, + childTransactions)]; - return PlacesUIUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions); + return PlacesUtils.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(PlacesUIUtils.ptm.createItem(uri, -1, -1, title)); + transactions.push(PlacesUtils.ptm.createItem(uri, -1, -1, title)); } return transactions; }, @@ -973,8 +973,8 @@ var BookmarkPropertiesPanel = { if (description) annotations.push(this._getDescriptionAnnotation(description)); - return PlacesUIUtils.ptm.createFolder(folderName, aContainer, aIndex, - annotations, childItemsTransactions); + return PlacesUtils.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 = PlacesUIUtils.createFixedURI(feedURIString); + var feedURI = PlacesUtils.createFixedURI(feedURIString); var siteURIString = this._element("feedSiteLocationTextfield").value; var siteURI = null; if (siteURIString) - siteURI = PlacesUIUtils.createFixedURI(siteURIString); + siteURI = PlacesUtils.createFixedURI(siteURIString); var name = this._element("namePicker").value; - return PlacesUIUtils.ptm.createLivemark(feedURI, siteURI, name, - aContainer, aIndex); + return PlacesUtils.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; - PlacesUIUtils.ptm.doTransaction(createTxn); + PlacesUtils.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=" + - PlacesUIUtils.allBookmarksFolderId; + PlacesUtils.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 4f0b7de924d..5884a4d22a3 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.PlacesUIUtils.allBookmarksFolderId; + "place:queryType=1&folder=" + window.top.PlacesUtils.allBookmarksFolderId; document.getElementById("search-box").focus(); } diff --git a/browser/components/places/content/controller.js b/browser/components/places/content/controller.js index 3ff5a0d1ebb..ff470ae38a7 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 PlacesUIUtils.ptm.numberOfUndoItems > 0; + return PlacesUtils.ptm.numberOfUndoItems > 0; case "cmd_redo": - return PlacesUIUtils.ptm.numberOfRedoItems > 0; + return PlacesUtils.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) && - PlacesUIUtils.microsummaries.hasMicrosummary(selectedNode.itemId); + PlacesUtils.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": - PlacesUIUtils.ptm.undoTransaction(); + PlacesUtils.ptm.undoTransaction(); break; case "cmd_redo": - PlacesUIUtils.ptm.redoTransaction(); + PlacesUtils.ptm.redoTransaction(); break; case "cmd_cut": this.cut(); @@ -213,13 +213,13 @@ PlacesController.prototype = { this.selectAll(); break; case "placesCmd_open": - PlacesUIUtils.openNodeIn(this._view.selectedNode, "current"); + PlacesUtils.openNodeIn(this._view.selectedNode, "current"); break; case "placesCmd_open:window": - PlacesUIUtils.openNodeIn(this._view.selectedNode, "window"); + PlacesUtils.openNodeIn(this._view.selectedNode, "window"); break; case "placesCmd_open:tab": - PlacesUIUtils.openNodeIn(this._view.selectedNode, "tab"); + PlacesUtils.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 = PlacesUIUtils.placesFlavors; - var clipboard = PlacesUIUtils.clipboard; + var flavors = PlacesUtils.placesFlavors; + var clipboard = PlacesUtils.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 = PlacesUIUtils.microsummaries; + var mss = PlacesUtils.microsummaries; if (mss.hasMicrosummary(node.itemId)) nodeData["microsummary"] = true; else if (node.parent && @@ -628,9 +628,9 @@ PlacesController.prototype = { return; if (PlacesUtils.nodeIsFolder(node)) - PlacesUIUtils.showFolderProperties(node.itemId); + PlacesUtils.showFolderProperties(node.itemId); else if (PlacesUtils.nodeIsBookmark(node)) - PlacesUIUtils.showBookmarkProperties(node.itemId); + PlacesUtils.showBookmarkProperties(node.itemId); }, /** @@ -656,7 +656,7 @@ PlacesController.prototype = { */ reloadSelectedMicrosummary: function PC_reloadSelectedMicrosummary() { var selectedNode = this._view.selectedNode; - var mss = PlacesUIUtils.microsummaries; + var mss = PlacesUtils.microsummaries; if (mss.hasMicrosummary(selectedNode.itemId)) mss.refreshMicrosummary(selectedNode.itemId); }, @@ -688,14 +688,14 @@ PlacesController.prototype = { GetStringFromName("brandShortName"); var buttonPressed = promptService.confirmEx(window, - PlacesUIUtils.getString("tabs.openWarningTitle"), - PlacesUIUtils.getFormattedString(messageKey, + PlacesUtils.getString("tabs.openWarningTitle"), + PlacesUtils.getFormattedString(messageKey, [numTabsToOpen, brandShortName]), (promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0) + (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1), - PlacesUIUtils.getString(openKey), + PlacesUtils.getString(openKey), null, null, - PlacesUIUtils.getFormattedString("tabs.openWarningPromptMeBranded", + PlacesUtils.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)) - PlacesUIUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent); + PlacesUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent); else - PlacesUIUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent); + PlacesUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent); }, /** @@ -732,11 +732,11 @@ PlacesController.prototype = { var performed = false; if (aType == "bookmark") - performed = PlacesUIUtils.showAddBookmarkUI(null, null, null, ip); + performed = PlacesUtils.showAddBookmarkUI(null, null, null, ip); else if (aType == "livemark") - performed = PlacesUIUtils.showAddLivemarkUI(null, null, null, null, ip); + performed = PlacesUtils.showAddLivemarkUI(null, null, null, null, ip); else // folder - performed = PlacesUIUtils.showAddFolderUI(null, ip); + performed = PlacesUtils.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 = PlacesUIUtils.showAddFolderUI(null, ip); + performed = PlacesUtils.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 = PlacesUIUtils.ptm.createSeparator(ip.itemId, ip.index); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.createSeparator(ip.itemId, ip.index); + PlacesUtils.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 = PlacesUIUtils.ptm.sortFolderByName(itemId); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.sortFolderByName(itemId); + PlacesUtils.ptm.doTransaction(txn); }, /** @@ -856,7 +856,7 @@ PlacesController.prototype = { if (PlacesUtils.nodeIsFolder(node)) removedFolders.push(node); - transactions.push(PlacesUIUtils.ptm.removeItem(node.itemId)); + transactions.push(PlacesUtils.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 = PlacesUIUtils.ptm.aggregateTransactions(txnName, transactions); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.aggregateTransactions(txnName, transactions); + PlacesUtils.ptm.doTransaction(txn); } }, @@ -997,7 +997,7 @@ PlacesController.prototype = { var data = new TransferData(); function addData(type, overrideURI) { - data.addDataForFlavour(type, PlacesUIUtils._wrapString( + data.addDataForFlavour(type, PlacesUtils._wrapString( PlacesUtils.wrapNode(node, type, overrideURI))); } @@ -1075,7 +1075,7 @@ PlacesController.prototype = { function addData(type, data) { xferable.addDataFlavor(type); - xferable.setTransferData(type, PlacesUIUtils._wrapString(data), data.length * 2); + xferable.setTransferData(type, PlacesUtils._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) { - PlacesUIUtils.clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard); + PlacesUtils.clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard); } } finally { @@ -1116,7 +1116,6 @@ 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. @@ -1134,7 +1133,7 @@ PlacesController.prototype = { return xferable; } - var clipboard = PlacesUIUtils.clipboard; + var clipboard = PlacesUtils.clipboard; var ip = this._view.insertionPoint; if (!ip) @@ -1162,9 +1161,9 @@ PlacesController.prototype = { // transactions insert differently if index == -1 if (ip.index > -1) index = ip.index + i; - transactions.push(PlacesUIUtils.makeTransaction(items[i], type.value, - ip.itemId, index, - true)); + transactions.push(PlacesUtils.makeTransaction(items[i], type.value, + ip.itemId, index, + true)); } return transactions; } @@ -1183,8 +1182,8 @@ PlacesController.prototype = { var transactions = getTransactions([PlacesUtils.TYPE_X_MOZ_PLACE, PlacesUtils.TYPE_X_MOZ_URL, PlacesUtils.TYPE_UNICODE]); - var txn = PlacesUIUtils.ptm.aggregateTransactions("Paste", transactions); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.aggregateTransactions("Paste", transactions); + PlacesUtils.ptm.doTransaction(txn); // select the pasted items, they should be consecutive var insertedNodeIds = []; @@ -1244,7 +1243,7 @@ var PlacesControllerDragHelper = { canDrop: function PCDH_canDrop() { var session = this.getSession(); if (session) { - var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES; + var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES; for (var i = 0; i < types.length; ++i) { if (session.isDataFlavorSupported(types[i])) return true; @@ -1264,7 +1263,7 @@ var PlacesControllerDragHelper = { _initTransferable: function PCDH__initTransferable(session) { var xferable = Cc["@mozilla.org/widget/transferable;1"]. createInstance(Ci.nsITransferable); - var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES; + var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES; for (var i = 0; i < types.length; ++i) { if (session.isDataFlavorSupported(types[i])) xferable.addDataFlavor(types[i]); @@ -1307,13 +1306,13 @@ var PlacesControllerDragHelper = { movedCount++; } - transactions.push(PlacesUIUtils.makeTransaction(unwrapped, + transactions.push(PlacesUtils.makeTransaction(unwrapped, flavor.value, insertionPoint.itemId, index, copy)); } - var txn = PlacesUIUtils.ptm.aggregateTransactions("DropItems", transactions); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.aggregateTransactions("DropItems", transactions); + PlacesUtils.ptm.doTransaction(txn); } }; diff --git a/browser/components/places/content/editBookmarkOverlay.js b/browser/components/places/content/editBookmarkOverlay.js index 586805568c7..d957f9f3a52 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", - PlacesUIUtils.getItemDescription(this._itemId)); + PlacesUtils.getItemDescription(this._itemId)); this._showHideRows(); @@ -324,8 +324,8 @@ var gEditItemOverlay = { try { if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK && !this._readOnly) - this._microsummaries = PlacesUIUtils.microsummaries - .getMicrosummaries(this._uri, -1); + this._microsummaries = PlacesUtils.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 (PlacesUIUtils.microsummaries - .isMicrosummary(this._itemId, microsummary)) + if (PlacesUtils.microsummaries + .isMicrosummary(this._itemId, microsummary)) itemToSelect = menuItem; menupopup.appendChild(menuItem); @@ -449,12 +449,12 @@ var gEditItemOverlay = { } if (tagsToAdd.length > 0) { - var tagTxn = PlacesUIUtils.ptm.tagURI(this._uri, tagsToAdd); - PlacesUIUtils.ptm.doTransaction(tagTxn); + var tagTxn = PlacesUtils.ptm.tagURI(this._uri, tagsToAdd); + PlacesUtils.ptm.doTransaction(tagTxn); } if (tagsToRemove.length > 0) { - var untagTxn = PlacesUIUtils.ptm.untagURI(this._uri, tagsToRemove); - PlacesUIUtils.ptm.doTransaction(untagTxn); + var untagTxn = PlacesUtils.ptm.untagURI(this._uri, tagsToRemove); + PlacesUtils.ptm.doTransaction(untagTxn); } } }, @@ -470,12 +470,12 @@ var gEditItemOverlay = { var namePicker = this._element("namePicker") var txns = []; - const ptm = PlacesUIUtils.ptm; + const ptm = PlacesUtils.ptm; // Here we update either the item title or its cached static title var newTitle = this._element("userEnteredName").label; if (this._getItemStaticTitle() != newTitle) { - if (PlacesUIUtils.microsummaries.hasMicrosummary(this._itemId)) { + if (PlacesUtils.microsummaries.hasMicrosummary(this._itemId)) { // Note: this implicitly also takes care of the microsummary->static // title case, the removeMicorosummary method in the service will set // the item-title to the value of this annotation. @@ -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 && - PlacesUIUtils.microsummaries.hasMicrosummary(this._itemId)) || + PlacesUtils.microsummaries.hasMicrosummary(this._itemId)) || (newMicrosummary != null && - !PlacesUIUtils.microsummaries - .isMicrosummary(this._itemId, newMicrosummary))) { + !PlacesUtils.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 = PlacesUIUtils.ptm - .editItemDescription(this._itemId, description); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm + .editItemDescription(this._itemId, description); + PlacesUtils.ptm.doTransaction(txn); } }, onLocationFieldBlur: function EIO_onLocationFieldBlur() { var uri; try { - uri = PlacesUIUtils.createFixedURI(this._element("locationField").value); + uri = PlacesUtils.createFixedURI(this._element("locationField").value); } catch(ex) { return; } if (!this._uri.equals(uri)) { - var txn = PlacesUIUtils.ptm.editBookmarkURI(this._itemId, uri); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.editBookmarkURI(this._itemId, uri); + PlacesUtils.ptm.doTransaction(txn); } }, onKeywordFieldBlur: function EIO_onKeywordFieldBlur() { var keyword = this._element("keywordField").value; if (keyword != PlacesUtils.bookmarks.getKeywordForBookmark(this._itemId)) { - var txn = PlacesUIUtils.ptm.editBookmarkKeyword(this._itemId, keyword); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.editBookmarkKeyword(this._itemId, keyword); + PlacesUtils.ptm.doTransaction(txn); } }, onFeedLocationFieldBlur: function EIO_onFeedLocationFieldBlur() { var uri; try { - uri = PlacesUIUtils.createFixedURI(this._element("feedLocationField").value); + uri = PlacesUtils.createFixedURI(this._element("feedLocationField").value); } catch(ex) { return; } var currentFeedURI = PlacesUtils.livemarks.getFeedURI(this._itemId); if (!currentFeedURI.equals(uri)) { - var txn = PlacesUIUtils.ptm.editLivemarkFeedURI(this._itemId, uri); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.editLivemarkFeedURI(this._itemId, uri); + PlacesUtils.ptm.doTransaction(txn); } }, onSiteLocationFieldBlur: function EIO_onSiteLocationFieldBlur() { var uri = null; try { - uri = PlacesUIUtils.createFixedURI(this._element("siteLocationField").value); + uri = PlacesUtils.createFixedURI(this._element("siteLocationField").value); } catch(ex) { } var currentSiteURI = PlacesUtils.livemarks.getSiteURI(this._itemId); if (!uri || !currentSiteURI.equals(uri)) { - var txn = PlacesUIUtils.ptm.editLivemarkSiteURI(this._itemId, uri); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.editLivemarkSiteURI(this._itemId, uri); + PlacesUtils.ptm.doTransaction(txn); } }, onLoadInSidebarCheckboxCommand: function EIO_onLoadInSidebarCheckboxCommand() { var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked; - var txn = PlacesUIUtils.ptm.setLoadInSidebar(this._itemId, - loadInSidebarChecked); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.setLoadInSidebar(this._itemId, + loadInSidebarChecked); + PlacesUtils.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.PlacesUIUtils.allBookmarksFolderId; + window.top.PlacesUtils.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 = PlacesUIUtils.ptm.moveItem(this._itemId, container, -1); - PlacesUIUtils.ptm.doTransaction(txn); + var txn = PlacesUtils.ptm.moveItem(this._itemId, container, -1); + PlacesUtils.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 e83a049924b..cd52ec41c10 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)) - PlacesUIUtils.showMinimalAddBookmarkUI(PlacesUtils._uri(node.uri), node.title); + PlacesUtils.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 29d1477d0e1..e824d538abe 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.restoreFromFile();"/> 0) @@ -829,7 +829,7 @@ PlacesTreeView.prototype = { { var uri = aNode.uri; NS_ASSERT(uri, "if there is no uri, we can't persist the open state"); - return uri ? PlacesUIUtils.RDF.GetResource(uri) : null; + return uri ? PlacesUtils.RDF.GetResource(uri) : null; }, // nsITreeView @@ -1117,7 +1117,7 @@ PlacesTreeView.prototype = { // if they go through the "result" API. if (PlacesUtils.nodeIsSeparator(node)) return ""; - return node.title || PlacesUIUtils.getString("noTitle"); + return node.title || PlacesUtils.getString("noTitle"); case this.COLUMN_TYPE_TAGS: return node.tags; case this.COLUMN_TYPE_URI: @@ -1191,13 +1191,13 @@ PlacesTreeView.prototype = { var resource = this._getResourceForNode(node); if (resource) { - const openLiteral = PlacesUIUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open"); - const trueLiteral = PlacesUIUtils.RDF.GetLiteral("true"); + const openLiteral = PlacesUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open"); + const trueLiteral = PlacesUtils.RDF.GetLiteral("true"); if (node.containerOpen) - PlacesUIUtils.localStore.Unassert(resource, openLiteral, trueLiteral); + PlacesUtils.localStore.Unassert(resource, openLiteral, trueLiteral); else - PlacesUIUtils.localStore.Assert(resource, openLiteral, trueLiteral, true); + PlacesUtils.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 5e1c2a5d52a..b46d541c721 100644 --- a/browser/components/places/content/utils.js +++ b/browser/components/places/content/utils.js @@ -23,7 +23,6 @@ * 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 @@ -47,11 +46,11 @@ var Ci = Components.interfaces; var Cc = Components.classes; var Cr = Components.results; -Components.utils.import("resource://gre/modules/utils.js"); -Components.utils.import("resource://gre/modules/debug.js"); +Components.utils.import("resource://gre/modules/JSON.jsm"); 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"; @@ -81,7 +80,71 @@ 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 PlacesUIUtils = { +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); + }, + /** * The Microsummary Service */ @@ -91,6 +154,15 @@ var PlacesUIUtils = { 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"]. @@ -120,6 +192,19 @@ var PlacesUIUtils = { 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 @@ -163,6 +248,416 @@ var PlacesUIUtils = { 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. @@ -175,7 +670,7 @@ var PlacesUIUtils = { * @returns A nsITransaction object that performs the copy. */ _getURIItemCopyTransaction: function (aData, aContainer, aIndex) { - return this.ptm.createItem(PlacesUtils._uri(aData.uri), aContainer, aIndex, + return this.ptm.createItem(this._uri(aData.uri), aContainer, aIndex, aData.title, ""); }, @@ -196,14 +691,15 @@ var PlacesUIUtils = { _getBookmarkItemCopyTransaction: function PU__getBookmarkItemCopyTransaction(aData, aContainer, aIndex, aExcludeAnnotations) { - var itemURL = PlacesUtils._uri(aData.uri); + var itemURL = this._uri(aData.uri); var itemTitle = aData.title; - var keyword = aData.keyword || null; - var annos = aData.annos || []; + var keyword = aData.keyword; + 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) @@ -243,23 +739,25 @@ var PlacesUIUtils = { if (aIndex > -1) index = aIndex + i; - 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, + 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, 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 == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR) + else if (node.type == self.TYPE_X_MOZ_PLACE_SEPARATOR) txn = self.ptm.createSeparator(-1, index); - else if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE) + else if (node.type == self.TYPE_X_MOZ_PLACE) txn = self._getBookmarkItemCopyTransaction(node, -1, index); NS_ASSERT(txn, "Unexpected item under a bookmarks folder"); @@ -269,51 +767,75 @@ var PlacesUIUtils = { return childItemsTransactions; } - // 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); - } + 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); }, - _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); + /** + * 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; }, /** @@ -335,42 +857,81 @@ var PlacesUIUtils = { makeTransaction: function PU_makeTransaction(data, type, container, index, copy) { switch (data.type) { - case PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER: + case this.TYPE_X_MOZ_PLACE_CONTAINER: + if (data.folder) { + // Place is a folder. if (copy) return this._getFolderCopyTransaction(data, container, index); - 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: + } + 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) { // 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 == 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); - } + } + 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; } - return null; + 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; }, /** @@ -746,8 +1307,7 @@ var PlacesUIUtils = { * TRANSITION_LINK. */ markPageAsTyped: function PU_markPageAsTyped(aURL) { - PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory) - .markPageAsTyped(this.createFixedURI(aURL)); + this.globalHistory.markPageAsTyped(this.createFixedURI(aURL)); }, /** @@ -758,7 +1318,7 @@ var PlacesUIUtils = { * If we don't call this, we'll treat those visits as TRANSITION_LINK. */ markPageAsFollowedBookmark: function PU_markPageAsFollowedBookmark(aURL) { - PlacesUtils.history.markPageAsFollowedBookmark(this.createFixedURI(aURL)); + this.history.markPageAsFollowedBookmark(this.createFixedURI(aURL)); }, /** @@ -770,8 +1330,8 @@ var PlacesUIUtils = { * */ checkURLSecurity: function PU_checkURLSecurity(aURINode) { - if (!PlacesUtils.nodeIsBookmark(aURINode)) { - var uri = PlacesUtils._uri(aURINode.uri); + if (!this.nodeIsBookmark(aURINode)) { + var uri = this._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"]. @@ -789,6 +1349,137 @@ var PlacesUIUtils = { 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. @@ -808,6 +1499,85 @@ var PlacesUIUtils = { 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 @@ -816,11 +1586,113 @@ var PlacesUIUtils = { * not set. */ getItemDescription: function PU_getItemDescription(aItemId) { - if (PlacesUtils.annotations.itemHasAnnotation(aItemId, DESCRIPTION_ANNO)) - return PlacesUtils.annotations.getItemAnnotation(aItemId, DESCRIPTION_ANNO); + if (this.annotations.itemHasAnnotation(aItemId, DESCRIPTION_ANNO)) + return this.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 */ @@ -895,7 +1767,7 @@ var PlacesUIUtils = { }, openContainerNodeInTabs: function PU_openContainerInTabs(aNode, aEvent) { - var urlsToOpen = PlacesUtils.getURLsForContainerNode(aNode); + var urlsToOpen = this.getURLsForContainerNode(aNode); if (!this._confirmOpenInTabs(urlsToOpen.length)) return; @@ -906,8 +1778,8 @@ var PlacesUIUtils = { var urlsToOpen = []; for (var i=0; i < aNodes.length; i++) { // skip over separators and folders - if (PlacesUtils.nodeIsURI(aNodes[i])) - urlsToOpen.push({uri: aNodes[i].uri, isBookmark: PlacesUtils.nodeIsBookmark(aNodes[i])}); + if (this.nodeIsURI(aNodes[i])) + urlsToOpen.push({uri: aNodes[i].uri, isBookmark: this.nodeIsBookmark(aNodes[i])}); } this._openTabset(urlsToOpen, aEvent); }, @@ -933,13 +1805,13 @@ var PlacesUIUtils = { */ openNodeIn: function PU_openNodeIn(aNode, aWhere) { if (aNode && PlacesUtils.nodeIsURI(aNode) && - this.checkURLSecurity(aNode)) { + PlacesUtils.checkURLSecurity(aNode)) { var isBookmark = PlacesUtils.nodeIsBookmark(aNode); if (isBookmark) - this.markPageAsFollowedBookmark(aNode.uri); + PlacesUtils.markPageAsFollowedBookmark(aNode.uri); else - this.markPageAsTyped(aNode.uri); + PlacesUtils.markPageAsTyped(aNode.uri); // Check whether the node is a bookmark which should be opened as // a web panel @@ -971,22 +1843,22 @@ var PlacesUIUtils = { if (iconURI) iconURISpec = iconURI.spec; - if (PlacesUtils.uriTypes.indexOf(type) != -1) { + if (this.uriTypes.indexOf(type) != -1) { element = document.createElement("menuitem"); element.setAttribute("statustext", aNode.uri); element.className = "menuitem-iconic bookmark-item"; } - else if (PlacesUtils.containerTypes.indexOf(type) != -1) { + else if (this.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 (PlacesUtils.nodeIsLivemarkContainer(aNode)) + if (this.nodeIsLivemarkContainer(aNode)) element.setAttribute("livemark", "true"); - else if (PlacesUtils.bookmarks. - getFolderIdForItem(aNode.itemId) == PlacesUtils.tagsFolderId) + else if (this.bookmarks + .getFolderIdForItem(aNode.itemId) == this.tagsFolderId) element.setAttribute("tagContainer", "true"); } @@ -1025,18 +1897,17 @@ var PlacesUIUtils = { get leftPaneFolderId() { var leftPaneRoot = -1; var allBookmarksId; - var items = PlacesUtils.annotations.getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO, {}); + var items = this.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 = PlacesUtils.annotations. - getItemsWithAnnotation(ORGANIZER_QUERY_ANNO, { }); + var items = this.annotations.getItemsWithAnnotation(ORGANIZER_QUERY_ANNO, { }); for (var i=0; i < items.length; i++) { - var queryName = PlacesUtils.annotations. - getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO); + var queryName = this.annotations + .getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO); this.leftPaneQueries[queryName] = items[i]; } delete this.leftPaneFolderId; @@ -1044,70 +1915,69 @@ var PlacesUIUtils = { } var self = this; - const EXPIRE_NEVER = PlacesUtils.annotations.EXPIRE_NEVER; + const EXPIRE_NEVER = this.annotations.EXPIRE_NEVER; var callback = { runBatched: function(aUserData) { delete self.leftPaneQueries; self.leftPaneQueries = { }; // Left Pane Root Folder - leftPaneRoot = - PlacesUtils.bookmarks.createFolder(PlacesUtils.placesRootId, "", -1); + leftPaneRoot = self.bookmarks.createFolder(self.placesRootId, "", -1); // History Query - let uri = PlacesUtils._uri("place:sort=4&"); + let uri = self._uri("place:sort=4&"); let title = self.getString("OrganizerQueryHistory"); - let itemId = PlacesUtils.bookmarks.insertBookmark(leftPaneRoot, uri, -1, title); - PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, - "History", 0, EXPIRE_NEVER); + let itemId = self.bookmarks.insertBookmark(leftPaneRoot, uri, -1, title); + self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, + "History", 0, EXPIRE_NEVER); self.leftPaneQueries["History"] = itemId; // XXX: Downloads // Tags Query - 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); + 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); self.leftPaneQueries["Tags"] = itemId; // All Bookmarks Folder title = self.getString("OrganizerQueryAllBookmarks"); - itemId = PlacesUtils.bookmarks.createFolder(leftPaneRoot, title, -1); + itemId = self.bookmarks.createFolder(leftPaneRoot, title, -1); allBookmarksId = itemId; - PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, - "AllBookmarks", 0, EXPIRE_NEVER); + self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, + "AllBookmarks", 0, EXPIRE_NEVER); self.leftPaneQueries["AllBookmarks"] = itemId; // All Bookmarks->Bookmarks Toolbar Query - 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); + 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); self.leftPaneQueries["BookmarksToolbar"] = itemId; // All Bookmarks->Bookmarks Menu Query - 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); + 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); self.leftPaneQueries["BookmarksMenu"] = itemId; // All Bookmarks->Unfiled bookmarks - 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); + 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); self.leftPaneQueries["UnfiledBookmarks"] = itemId; // disallow manipulating this folder within the organizer UI - PlacesUtils.bookmarks.setFolderReadonly(leftPaneRoot, true); + self.bookmarks.setFolderReadonly(leftPaneRoot, true); } }; - PlacesUtils.bookmarks.runInBatchMode(callback, null); - PlacesUtils.annotations.setItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO, - true, 0, EXPIRE_NEVER); + this.bookmarks.runInBatchMode(callback, null); + this.annotations.setItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO, + true, 0, EXPIRE_NEVER); delete this.leftPaneFolderId; return this.leftPaneFolderId = leftPaneRoot; }, @@ -1120,12 +1990,12 @@ var PlacesUIUtils = { } }; -PlacesUIUtils.placesFlavors = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, - PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, - PlacesUtils.TYPE_X_MOZ_PLACE]; +PlacesUtils.placesFlavors = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, + PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, + PlacesUtils.TYPE_X_MOZ_PLACE]; -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]; +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]; diff --git a/browser/components/places/src/Makefile.in b/browser/components/places/src/Makefile.in index e1b30a90ce7..a30e6ffecec 100644 --- a/browser/components/places/src/Makefile.in +++ b/browser/components/places/src/Makefile.in @@ -67,8 +67,6 @@ 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 8b7508ffe33..9025bf5d9db 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,7 +2440,9 @@ 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() @@ -2456,6 +2458,15 @@ 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)); @@ -2472,6 +2483,17 @@ 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; } @@ -2487,7 +2509,7 @@ nsPlacesImportExportService::BackupBookmarksFile() */ nsresult nsPlacesImportExportService::ArchiveBookmarksFile(PRInt32 numberOfBackups, - PRBool forceArchive) + PRBool forceArchive) { nsCOMPtr bookmarksBackupDir; nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, @@ -2508,7 +2530,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); @@ -2519,6 +2541,8 @@ 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; @@ -2585,6 +2609,18 @@ 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 e27a4d04502..5601e2db2aa 100644 --- a/browser/components/places/src/nsPlacesTransactionsService.js +++ b/browser/components/places/src/nsPlacesTransactionsService.js @@ -37,18 +37,17 @@ * * ***** 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"); -Components.utils.import("resource://gre/modules/utils.js"); -Components.utils.import("resource://gre/modules/debug.js"); // The minimum amount of transactions we should tell our observers to begin // batching (rather than letting them do incremental drawing). diff --git a/browser/components/places/tests/unit/head_bookmarks.js b/browser/components/places/tests/unit/head_bookmarks.js index e087eac6e9c..df5fcd80906 100644 --- a/browser/components/places/tests/unit/head_bookmarks.js +++ b/browser/components/places/tests/unit/head_bookmarks.js @@ -37,8 +37,6 @@ * * ***** 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_398914.js b/browser/components/places/tests/unit/test_398914.js index 5c8b39e084c..37187e1d339 100644 --- a/browser/components/places/tests/unit/test_398914.js +++ b/browser/components/places/tests/unit/test_398914.js @@ -36,7 +36,12 @@ * * ***** END LICENSE BLOCK ***** */ -Components.utils.import("resource://gre/modules/utils.js"); +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"); 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 f7ef1f1e9b1..04fcfbf7aa8 100644 --- a/browser/components/places/tests/unit/test_bookmarks_html.js +++ b/browser/components/places/tests/unit/test_bookmarks_html.js @@ -78,6 +78,7 @@ 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 159b4d94e39..991960514ef 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.PlacesUIUtils.showMinimalAddBookmarkUI(uri, aTitle, null, null, true, true); + win.PlacesUtils.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 1fa4d742976..2dda865e518 100644 --- a/toolkit/components/places/src/Makefile.in +++ b/toolkit/components/places/src/Makefile.in @@ -102,8 +102,4 @@ 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 d1deaa4016d..0426a933d6f 100644 --- a/toolkit/components/places/src/nsTaggingService.js +++ b/toolkit/components/places/src/nsTaggingService.js @@ -194,14 +194,13 @@ TaggingService.prototype = { * the item-id of the tag element under the tags root */ _removeTagIfEmpty: function TS__removeTagIfEmpty(aTagId) { - 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) + 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) this._bms.removeFolder(aTagId); }, diff --git a/toolkit/content/Makefile.in b/toolkit/content/Makefile.in index 45881f489e2..fb08abf0ac4 100644 --- a/toolkit/content/Makefile.in +++ b/toolkit/content/Makefile.in @@ -51,9 +51,6 @@ ifdef ENABLE_TESTS DIRS += tests endif -EXTRA_JS_MODULES = debug.js -EXTRA_PP_JS_MODULES = debug.js - include $(topsrcdir)/config/rules.mk distclean:: diff --git a/toolkit/content/debug.js b/toolkit/content/debug.js index a8552b46530..7287c49514d 100644 --- a/toolkit/content/debug.js +++ b/toolkit/content/debug.js @@ -42,8 +42,6 @@ # This file contains functions that are useful for debugging purposes from # within JavaScript code. -var EXPORTED_SYMBOLS = ["NS_ASSERT"]; - var gTraceOnAssert = true; /** diff --git a/toolkit/content/globalOverlay.js b/toolkit/content/globalOverlay.js index 196b18e09c5..6efa76500a3 100644 --- a/toolkit/content/globalOverlay.js +++ b/toolkit/content/globalOverlay.js @@ -196,4 +196,4 @@ function FillInTooltip ( tipElement ) return retVal; } -Components.utils.import("resource://gre/modules/debug.js"); +#include debug.js diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn index a04cae42be5..d51c9c2ca8b 100644 --- a/toolkit/content/jar.mn +++ b/toolkit/content/jar.mn @@ -11,6 +11,7 @@ toolkit.jar: * content/global/about.xhtml (about.xhtml) content/global/plugins.html content/global/plugins.css +* content/global/debug.js (debug.js) + content/global/buildconfig.html (buildconfig.html) + content/global/charsetOverlay.js (charsetOverlay.js) + content/global/charsetOverlay.xul (charsetOverlay.xul)