1 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is the Places Command Controller.
17 * The Initial Developer of the Original Code is Google Inc.
19 * Portions created by the Initial Developer are Copyright (C) 2005
20 * the Initial Developer. All Rights Reserved.
23 * Sungjoon Steve Won <stevewon@gmail.com> (Original Author)
24 * Asaf Romano <mano@mozilla.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 let Ci
= Components
.interfaces
;
41 let Cc
= Components
.classes
;
42 let Cr
= Components
.results
;
44 const loadInSidebarAnno
= "bookmarkProperties/loadInSidebar";
45 const descriptionAnno
= "bookmarkProperties/description";
46 const CLASS_ID
= Components
.ID("c0844a84-5a12-4808-80a8-809cb002bb4f");
47 const CONTRACT_ID
= "@mozilla.org/browser/placesTransactionsService;1";
49 Components
.utils
.import("resource://gre/modules/XPCOMUtils.jsm");
51 __defineGetter__("PlacesUtils", function() {
52 delete this.PlacesUtils
54 Components
.utils
.import("resource://gre/modules/utils.js", tmpScope
);
55 return this.PlacesUtils
= tmpScope
.PlacesUtils
;
58 // The minimum amount of transactions we should tell our observers to begin
59 // batching (rather than letting them do incremental drawing).
60 const MIN_TRANSACTIONS_FOR_BATCH
= 5;
62 function placesTransactionsService() {
63 this.mTransactionManager
= Cc
["@mozilla.org/transactionmanager;1"].
64 createInstance(Ci
.nsITransactionManager
);
67 placesTransactionsService
.prototype = {
68 classDescription
: "Places Transaction Manager",
70 contractID
: CONTRACT_ID
,
72 QueryInterface
: XPCOMUtils
.generateQI([Ci
.nsIPlacesTransactionsService
,
73 Ci
.nsITransactionManager
]),
75 aggregateTransactions
: function placesAggrTransactions(name
, transactions
) {
76 return new placesAggregateTransactions(name
, transactions
);
79 createFolder
: function placesCrtFldr(aName
, aContainer
, aIndex
,
80 aAnnotations
, aChildItemsTransactions
) {
81 return new placesCreateFolderTransactions(aName
, aContainer
, aIndex
,
82 aAnnotations
, aChildItemsTransactions
);
85 createItem
: function placesCrtItem(aURI
, aContainer
, aIndex
, aTitle
,
86 aKeyword
, aAnnotations
, aChildTransactions
) {
87 return new placesCreateItemTransactions(aURI
, aContainer
, aIndex
, aTitle
,
88 aKeyword
, aAnnotations
, aChildTransactions
);
91 createSeparator
: function placesCrtSpr(aContainer
, aIndex
) {
92 return new placesCreateSeparatorTransactions(aContainer
, aIndex
);
95 createLivemark
: function placesCrtLivemark(aFeedURI
, aSiteURI
, aName
,
96 aContainer
, aIndex
, aAnnotations
) {
97 return new placesCreateLivemarkTransactions(aFeedURI
, aSiteURI
, aName
,
98 aContainer
, aIndex
, aAnnotations
);
101 moveItem
: function placesMvItem(aItemId
, aNewContainer
, aNewIndex
) {
102 return new placesMoveItemTransactions(aItemId
, aNewContainer
, aNewIndex
);
105 removeItem
: function placesRmItem(id
) {
106 if (id
== PlacesUtils
.tagsFolderId
|| id
== PlacesUtils
.placesRootId
||
107 id
== PlacesUtils
.bookmarksMenuFolderId
||
108 id
== PlacesUtils
.toolbarFolderId
)
109 throw Cr
.NS_ERROR_INVALID_ARG
;
111 // if the item lives within a tag container, use the tagging transactions
112 var parent
= PlacesUtils
.bookmarks
.getFolderIdForItem(id
);
113 var grandparent
= PlacesUtils
.bookmarks
.getFolderIdForItem(parent
);
114 if (grandparent
== PlacesUtils
.tagsFolderId
) {
115 var uri
= PlacesUtils
.bookmarks
.getBookmarkURI(id
);
116 return this.untagURI(uri
, [parent
]);
119 return new placesRemoveItemTransaction(id
);
122 editItemTitle
: function placesEditItmTitle(id
, newTitle
) {
123 return new placesEditItemTitleTransactions(id
, newTitle
);
126 editBookmarkURI
: function placesEditBkmkURI(aBookmarkId
, aNewURI
) {
127 return new placesEditBookmarkURITransactions(aBookmarkId
, aNewURI
);
130 setLoadInSidebar
: function placesSetLdInSdbar(aBookmarkId
, aLoadInSidebar
) {
131 return new placesSetLoadInSidebarTransactions(aBookmarkId
, aLoadInSidebar
);
134 editItemDescription
: function placesEditItmDesc(aItemId
, aDescription
) {
135 return new placesEditItemDescriptionTransactions(aItemId
, aDescription
);
138 editBookmarkKeyword
: function placesEditBkmkKwd(aItemId
, newKeyword
) {
139 return new placesEditBookmarkKeywordTransactions(aItemId
, newKeyword
);
142 editBookmarkPostData
: function placesEditBookmarkPostdata(aItemId
, aPostData
) {
143 return new placesEditBookmarkPostDataTransactions(aItemId
, aPostData
);
146 editLivemarkSiteURI
: function placesEditLvmkSiteURI(folderId
, uri
) {
147 return new placesEditLivemarkSiteURITransactions(folderId
, uri
);
150 editLivemarkFeedURI
: function placesEditLvmkFeedURI(folderId
, uri
) {
151 return new placesEditLivemarkFeedURITransactions(folderId
, uri
);
154 editBookmarkMicrosummary
: function placesEditBkmkMicrosummary(aID
, newMicrosummary
) {
155 return new placesEditBookmarkMicrosummaryTransactions(aID
, newMicrosummary
);
158 editItemDateAdded
: function placesEditItemDateAdded(aID
, aNewDateAdded
) {
159 return new placesEditItemDateAddedTransaction(aID
, aNewDateAdded
);
162 editItemLastModified
: function placesEditItemLastModified(aID
, aNewLastModified
) {
163 return new placesEditItemLastModifiedTransaction(aID
, aNewLastModified
);
166 sortFolderByName
: function placesSortFldrByName(aFolderId
) {
167 return new placesSortFolderByNameTransactions(aFolderId
);
170 tagURI
: function placesTagURI(aURI
, aTags
) {
171 return new placesTagURITransaction(aURI
, aTags
);
174 untagURI
: function placesUntagURI(aURI
, aTags
) {
175 return new placesUntagURITransaction(aURI
, aTags
);
178 // Update commands in the undo group of the active window
179 // commands in inactive windows will are updated on-focus
180 _updateCommands: function() {
181 var wm
= Cc
["@mozilla.org/appshell/window-mediator;1"].
182 getService(Ci
.nsIWindowMediator
);
183 var win
= wm
.getMostRecentWindow(null);
185 win
.updateCommands("undo");
188 // nsITransactionManager
189 doTransaction
: function doTransaction(txn
) {
190 this.mTransactionManager
.doTransaction(txn
);
191 this._updateCommands();
194 undoTransaction
: function undoTransaction() {
195 this.mTransactionManager
.undoTransaction();
196 this._updateCommands();
199 redoTransaction
: function redoTransaction() {
200 this.mTransactionManager
.redoTransaction();
201 this._updateCommands();
204 clear: function() this.mTransactionManager
.clear(),
205 beginBatch: function() this.mTransactionManager
.beginBatch(),
206 endBatch: function() this.mTransactionManager
.endBatch(),
208 get numberOfUndoItems() {
209 return this.mTransactionManager
.numberOfUndoItems
;
212 get numberOfRedoItems() {
213 return this.mTransactionManager
.numberOfRedoItems
;
216 get maxTransactionCount() {
217 return this.mTransactionManager
.maxTransactionCount
;
219 set maxTransactionCount(val
) {
220 return this.mTransactionManager
.maxTransactionCount
= val
;
223 peekUndoStack: function() this.mTransactionManager
.peekUndoStack(),
224 peekRedoStack: function() this.mTransactionManager
.peekRedoStack(),
225 getUndoStack: function() this.mTransactionManager
.getUndoStack(),
226 getRedoStack: function() this.mTransactionManager
.getRedoStack(),
227 AddListener: function(l
) this.mTransactionManager
.AddListener(l
),
228 RemoveListener: function(l
) this.mTransactionManager
.RemoveListener(l
)
232 * Method and utility stubs for Places Edit Transactions
234 function placesBaseTransaction() {
237 placesBaseTransaction
.prototype = {
238 // for child-transactions
239 get wrappedJSObject() {
244 redoTransaction
: function PBT_redoTransaction() {
245 throw Cr
.NS_ERROR_NOT_IMPLEMENTED
;
252 merge
: function mergeFunc(transaction
) {
257 QueryInterface
: XPCOMUtils
.generateQI([Ci
.nsITransaction
]),
260 function placesAggregateTransactions(name
, transactions
) {
261 this._transactions
= transactions
;
264 this.redoTransaction
= this.doTransaction
;
267 placesAggregateTransactions
.prototype = {
268 __proto__
: placesBaseTransaction
.prototype,
270 doTransaction
: function PAT_doTransaction() {
271 if (this._transactions
.length
>= MIN_TRANSACTIONS_FOR_BATCH
) {
274 runBatched: function() {
275 this._self
.commit(false);
278 PlacesUtils
.bookmarks
.runInBatchMode(callback
, null);
284 undoTransaction
: function PAT_undoTransaction() {
285 if (this._transactions
.length
>= MIN_TRANSACTIONS_FOR_BATCH
) {
288 runBatched: function() {
289 this._self
.commit(true);
292 PlacesUtils
.bookmarks
.runInBatchMode(callback
, null);
298 commit
: function PAT_commit(aUndo
) {
299 var transactions
= this._transactions
;
301 transactions
.reverse();
302 for (var i
= 0; i
< transactions
.length
; i
++) {
303 var txn
= transactions
[i
];
304 if (this.container
> -1)
305 txn
.wrappedJSObject
.container
= this.container
;
307 txn
.undoTransaction();
314 function placesCreateFolderTransactions(aName
, aContainer
, aIndex
,
316 aChildItemsTransactions
) {
318 this._container
= aContainer
;
319 this._index
= typeof(aIndex
) == "number" ? aIndex
: -1;
320 this._annotations
= aAnnotations
;
322 this._childItemsTransactions
= aChildItemsTransactions
|| [];
323 this.redoTransaction
= this.doTransaction
;
326 placesCreateFolderTransactions
.prototype = {
327 __proto__
: placesBaseTransaction
.prototype,
329 // childItemsTransaction support
330 get container() { return this._container
; },
331 set container(val
) { return this._container
= val
; },
333 doTransaction
: function PCFT_doTransaction() {
334 this._id
= PlacesUtils
.bookmarks
.createFolder(this._container
,
335 this._name
, this._index
);
336 if (this._annotations
&& this._annotations
.length
> 0)
337 PlacesUtils
.setAnnotationsForItem(this._id
, this._annotations
);
339 for (var i
= 0; i
< this._childItemsTransactions
.length
; ++i
) {
340 var txn
= this._childItemsTransactions
[i
];
341 txn
.wrappedJSObject
.container
= this._id
;
346 undoTransaction
: function PCFT_undoTransaction() {
347 for (var i
= 0; i
< this._childItemsTransactions
.length
; ++i
) {
348 var txn
= this._childItemsTransactions
[i
];
349 txn
.undoTransaction();
351 PlacesUtils
.bookmarks
.removeFolder(this._id
);
355 function placesCreateItemTransactions(aURI
, aContainer
, aIndex
, aTitle
,
356 aKeyword
, aAnnotations
,
357 aChildTransactions
) {
359 this._container
= aContainer
;
360 this._index
= typeof(aIndex
) == "number" ? aIndex
: -1;
361 this._title
= aTitle
;
362 this._keyword
= aKeyword
;
363 this._annotations
= aAnnotations
;
364 this._childTransactions
= aChildTransactions
|| [];
365 this.redoTransaction
= this.doTransaction
;
368 placesCreateItemTransactions
.prototype = {
369 __proto__
: placesBaseTransaction
.prototype,
371 // childItemsTransactions support for the create-folder transaction
372 get container() { return this._container
; },
373 set container(val
) { return this._container
= val
; },
375 doTransaction
: function PCIT_doTransaction() {
376 this._id
= PlacesUtils
.bookmarks
.insertBookmark(this.container
, this._uri
,
377 this._index
, this._title
);
379 PlacesUtils
.bookmarks
.setKeywordForBookmark(this._id
, this._keyword
);
380 if (this._annotations
&& this._annotations
.length
> 0)
381 PlacesUtils
.setAnnotationsForItem(this._id
, this._annotations
);
383 for (var i
= 0; i
< this._childTransactions
.length
; ++i
) {
384 var txn
= this._childTransactions
[i
];
385 txn
.wrappedJSObject
.id
= this._id
;
390 undoTransaction
: function PCIT_undoTransaction() {
391 PlacesUtils
.bookmarks
.removeItem(this._id
);
392 for (var i
= 0; i
< this._childTransactions
.length
; ++i
) {
393 var txn
= this._childTransactions
[i
];
394 txn
.undoTransaction();
399 function placesCreateSeparatorTransactions(aContainer
, aIndex
) {
400 this._container
= aContainer
;
401 this._index
= typeof(aIndex
) == "number" ? aIndex
: -1;
403 this.redoTransaction
= this.doTransaction
;
406 placesCreateSeparatorTransactions
.prototype = {
407 __proto__
: placesBaseTransaction
.prototype,
409 // childItemsTransaction support
410 get container() { return this._container
; },
411 set container(val
) { return this._container
= val
; },
413 doTransaction
: function PCST_doTransaction() {
414 this._id
= PlacesUtils
.bookmarks
415 .insertSeparator(this.container
, this._index
);
418 undoTransaction
: function PCST_undoTransaction() {
419 PlacesUtils
.bookmarks
.removeItem(this._id
);
423 function placesCreateLivemarkTransactions(aFeedURI
, aSiteURI
, aName
,
426 this._feedURI
= aFeedURI
;
427 this._siteURI
= aSiteURI
;
429 this._container
= aContainer
;
430 this._index
= typeof(aIndex
) == "number" ? aIndex
: -1;
431 this._annotations
= aAnnotations
;
434 placesCreateLivemarkTransactions
.prototype = {
435 __proto__
: placesBaseTransaction
.prototype,
437 // childItemsTransaction support
438 get container() { return this._container
; },
439 set container(val
) { return this._container
= val
; },
441 doTransaction
: function PCLT_doTransaction() {
442 this._id
= PlacesUtils
.livemarks
.createLivemark(this._container
, this._name
,
443 this._siteURI
, this._feedURI
,
445 if (this._annotations
&& this._annotations
.length
> 0)
446 PlacesUtils
.setAnnotationsForItem(this._id
, this._annotations
);
449 undoTransaction
: function PCLT_undoTransaction() {
450 PlacesUtils
.bookmarks
.removeFolder(this._id
);
454 function placesMoveItemTransactions(aItemId
, aNewContainer
, aNewIndex
) {
456 this._oldContainer
= PlacesUtils
.bookmarks
.getFolderIdForItem(this._id
);
457 this._newContainer
= aNewContainer
;
458 this._newIndex
= aNewIndex
;
459 this.redoTransaction
= this.doTransaction
;
462 placesMoveItemTransactions
.prototype = {
463 __proto__
: placesBaseTransaction
.prototype,
465 doTransaction
: function PMIT_doTransaction() {
466 this._oldIndex
= PlacesUtils
.bookmarks
.getItemIndex(this._id
);
467 PlacesUtils
.bookmarks
.moveItem(this._id
, this._newContainer
, this._newIndex
);
468 this._undoIndex
= PlacesUtils
.bookmarks
.getItemIndex(this._id
);
471 undoTransaction
: function PMIT_undoTransaction() {
472 // moving down in the same container takes in count removal of the item
473 // so to revert positions we must move to oldIndex + 1
474 if (this._newContainer
== this._oldContainer
&&
475 this._oldIndex
> this._undoIndex
)
476 PlacesUtils
.bookmarks
.moveItem(this._id
, this._oldContainer
, this._oldIndex
+ 1);
478 PlacesUtils
.bookmarks
.moveItem(this._id
, this._oldContainer
, this._oldIndex
);
482 function placesRemoveItemTransaction(aItemId
) {
483 this.redoTransaction
= this.doTransaction
;
485 this._itemType
= PlacesUtils
.bookmarks
.getItemType(this._id
);
486 if (this._itemType
== Ci
.nsINavBookmarksService
.TYPE_FOLDER
) {
487 this._transactions
= [];
488 this._removeTxn
= PlacesUtils
.bookmarks
489 .getRemoveFolderTransaction(this._id
);
493 placesRemoveItemTransaction
.prototype = {
494 __proto__
: placesBaseTransaction
.prototype,
496 doTransaction
: function PRIT_doTransaction() {
497 this._oldContainer
= PlacesUtils
.bookmarks
.getFolderIdForItem(this._id
);
498 this._oldIndex
= PlacesUtils
.bookmarks
.getItemIndex(this._id
);
499 this._title
= PlacesUtils
.bookmarks
.getItemTitle(this._id
);
500 this._annotations
= PlacesUtils
.getAnnotationsForItem(this._id
);
501 this._dateAdded
= PlacesUtils
.bookmarks
.getItemDateAdded(this._id
);
502 this._lastModified
= PlacesUtils
.bookmarks
.getItemLastModified(this._id
);
504 if (this._itemType
== Ci
.nsINavBookmarksService
.TYPE_FOLDER
) {
505 this._saveFolderContents();
507 // Remove children backwards to preserve parent-child relationships.
508 for (var i
= this._transactions
.length
- 1; i
>= 0; --i
)
509 this._transactions
[i
].doTransaction();
511 // Remove this folder itself.
512 this._removeTxn
.doTransaction();
515 if (this._itemType
== Ci
.nsINavBookmarksService
.TYPE_BOOKMARK
)
516 this._uri
= PlacesUtils
.bookmarks
.getBookmarkURI(this._id
);
517 PlacesUtils
.bookmarks
.removeItem(this._id
);
519 // if this was the last bookmark (excluding tag-items and livemark
520 // children, see getMostRecentBookmarkForURI) for the bookmark's url,
521 // remove the url from tag containers as well.
522 if (PlacesUtils
.getMostRecentBookmarkForURI(this._uri
) == -1) {
523 this._tags
= PlacesUtils
.tagging
.getTagsForURI(this._uri
, {});
524 PlacesUtils
.tagging
.untagURI(this._uri
, this._tags
);
530 undoTransaction
: function PRIT_undoTransaction() {
531 if (this._itemType
== Ci
.nsINavBookmarksService
.TYPE_BOOKMARK
) {
532 this._id
= PlacesUtils
.bookmarks
.insertBookmark(this._oldContainer
,
536 if (this._tags
&& this._tags
.length
> 0)
537 PlacesUtils
.tagging
.tagURI(this._uri
, this._tags
);
539 else if (this._itemType
== Ci
.nsINavBookmarksService
.TYPE_FOLDER
) {
540 this._removeTxn
.undoTransaction();
541 // Create children forwards to preserve parent-child relationships.
542 for (var i
= 0; i
< this._transactions
.length
; ++i
)
543 this._transactions
[i
].undoTransaction();
545 else // TYPE_SEPARATOR
546 this._id
= PlacesUtils
.bookmarks
.insertSeparator(this._oldContainer
, this._oldIndex
);
548 if (this._annotations
.length
> 0)
549 PlacesUtils
.setAnnotationsForItem(this._id
, this._annotations
);
551 PlacesUtils
.bookmarks
.setItemDateAdded(this._id
, this._dateAdded
);
552 PlacesUtils
.bookmarks
.setItemLastModified(this._id
, this._lastModified
);
556 * Create a flat, ordered list of transactions for a depth-first recreation
557 * of items within this folder.
559 _saveFolderContents
: function PRIT__saveFolderContents() {
560 this._transactions
= [];
562 PlacesUtils
.getFolderContents(this._id
, false, false).root
;
563 for (var i
= 0; i
< contents
.childCount
; ++i
) {
565 .push(new placesRemoveItemTransaction(contents
.getChild(i
).itemId
));
570 function placesEditItemTitleTransactions(id
, newTitle
) {
572 this._newTitle
= newTitle
;
574 this.redoTransaction
= this.doTransaction
;
577 placesEditItemTitleTransactions
.prototype = {
578 __proto__
: placesBaseTransaction
.prototype,
580 doTransaction
: function PEITT_doTransaction() {
581 this._oldTitle
= PlacesUtils
.bookmarks
.getItemTitle(this._id
);
582 PlacesUtils
.bookmarks
.setItemTitle(this._id
, this._newTitle
);
585 undoTransaction
: function PEITT_undoTransaction() {
586 PlacesUtils
.bookmarks
.setItemTitle(this._id
, this._oldTitle
);
590 function placesEditBookmarkURITransactions(aBookmarkId
, aNewURI
) {
591 this._id
= aBookmarkId
;
592 this._newURI
= aNewURI
;
593 this.redoTransaction
= this.doTransaction
;
596 placesEditBookmarkURITransactions
.prototype = {
597 __proto__
: placesBaseTransaction
.prototype,
599 doTransaction
: function PEBUT_doTransaction() {
600 this._oldURI
= PlacesUtils
.bookmarks
.getBookmarkURI(this._id
);
601 PlacesUtils
.bookmarks
.changeBookmarkURI(this._id
, this._newURI
);
602 // move tags from old URI to new URI
603 this._tags
= PlacesUtils
.tagging
.getTagsForURI(this._oldURI
, {});
604 if (this._tags
.length
!= 0) {
605 // only untag the old URI if this is the only bookmark
606 if (PlacesUtils
.getBookmarksForURI(this._oldURI
, {}).length
== 0)
607 PlacesUtils
.tagging
.untagURI(this._oldURI
, this._tags
);
608 PlacesUtils
.tagging
.tagURI(this._newURI
, this._tags
);
612 undoTransaction
: function PEBUT_undoTransaction() {
613 PlacesUtils
.bookmarks
.changeBookmarkURI(this._id
, this._oldURI
);
614 // move tags from new URI to old URI
615 if (this._tags
.length
!= 0) {
616 // only untag the new URI if this is the only bookmark
617 if (PlacesUtils
.getBookmarksForURI(this._newURI
, {}).length
== 0)
618 PlacesUtils
.tagging
.untagURI(this._newURI
, this._tags
);
619 PlacesUtils
.tagging
.tagURI(this._oldURI
, this._tags
);
624 function placesSetLoadInSidebarTransactions(aBookmarkId
, aLoadInSidebar
) {
625 this.id
= aBookmarkId
;
626 this._loadInSidebar
= aLoadInSidebar
;
627 this.redoTransaction
= this.doTransaction
;
630 placesSetLoadInSidebarTransactions
.prototype = {
631 __proto__
: placesBaseTransaction
.prototype,
634 name
: loadInSidebarAnno
,
635 type
: Ci
.nsIAnnotationService
.TYPE_INT32
,
638 expires
: Ci
.nsIAnnotationService
.EXPIRE_NEVER
641 doTransaction
: function PSLIST_doTransaction() {
642 this._wasSet
= PlacesUtils
.annotations
.itemHasAnnotation(this.id
, this._anno
.name
);
643 if (this._loadInSidebar
) {
644 PlacesUtils
.setAnnotationsForItem(this.id
, [this._anno
]);
648 PlacesUtils
.annotations
.removeItemAnnotation(this.id
, this._anno
.name
);
653 undoTransaction
: function PSLIST_undoTransaction() {
654 if (this._wasSet
!= this._loadInSidebar
) {
655 this._loadInSidebar
= !this._loadInSidebar
;
656 this.doTransaction();
661 function placesEditItemDescriptionTransactions(aItemId
, aDescription
) {
663 this._newDescription
= aDescription
;
664 this.redoTransaction
= this.doTransaction
;
667 placesEditItemDescriptionTransactions
.prototype = {
668 __proto__
: placesBaseTransaction
.prototype,
672 doTransaction
: function PSLIST_doTransaction() {
673 const annos
= PlacesUtils
.annotations
;
674 if (annos
.itemHasAnnotation(this.id
, descriptionAnno
))
675 this._oldDescription
= annos
.getItemAnnotation(this.id
, descriptionAnno
);
677 if (this._newDescription
) {
678 annos
.setItemAnnotation(this.id
, descriptionAnno
,
679 this._newDescription
, 0,
682 else if (this._oldDescription
)
683 annos
.removeItemAnnotation(this.id
, descriptionAnno
);
686 undoTransaction
: function PSLIST_undoTransaction() {
687 const annos
= PlacesUtils
.annotations
;
688 if (this._oldDescription
) {
689 annos
.setItemAnnotationString(this.id
, descriptionAnno
,
690 this._oldDescription
, 0,
693 else if (annos
.itemHasAnnotation(this.id
, descriptionAnno
))
694 annos
.removeItemAnnotation(this.id
, descriptionAnno
);
698 function placesEditBookmarkKeywordTransactions(id
, newKeyword
) {
700 this._newKeyword
= newKeyword
;
701 this._oldKeyword
= "";
702 this.redoTransaction
= this.doTransaction
;
705 placesEditBookmarkKeywordTransactions
.prototype = {
706 __proto__
: placesBaseTransaction
.prototype,
708 doTransaction
: function PEBKT_doTransaction() {
709 this._oldKeyword
= PlacesUtils
.bookmarks
.getKeywordForBookmark(this.id
);
710 PlacesUtils
.bookmarks
.setKeywordForBookmark(this.id
, this._newKeyword
);
713 undoTransaction
: function PEBKT_undoTransaction() {
714 PlacesUtils
.bookmarks
.setKeywordForBookmark(this.id
, this._oldKeyword
);
718 function placesEditBookmarkPostDataTransactions(aItemId
, aPostData
) {
720 this._newPostData
= aPostData
;
721 this._oldPostData
= null;
722 this.redoTransaction
= this.doTransaction
;
725 placesEditBookmarkPostDataTransactions
.prototype = {
726 __proto__
: placesBaseTransaction
.prototype,
728 doTransaction
: function PEUPDT_doTransaction() {
729 this._oldPostData
= PlacesUtils
.getPostDataForBookmark(this._id
);
730 PlacesUtils
.setPostDataForBookmark(this.id
, this._newPostData
);
733 undoTransaction
: function PEUPDT_undoTransaction() {
734 PlacesUtils
.setPostDataForBookmark(this.id
, this._oldPostData
);
738 function placesEditLivemarkSiteURITransactions(folderId
, uri
) {
739 this._folderId
= folderId
;
742 this.redoTransaction
= this.doTransaction
;
745 placesEditLivemarkSiteURITransactions
.prototype = {
746 __proto__
: placesBaseTransaction
.prototype,
748 doTransaction
: function PELSUT_doTransaction() {
749 this._oldURI
= PlacesUtils
.livemarks
.getSiteURI(this._folderId
);
750 PlacesUtils
.livemarks
.setSiteURI(this._folderId
, this._newURI
);
753 undoTransaction
: function PELSUT_undoTransaction() {
754 PlacesUtils
.livemarks
.setSiteURI(this._folderId
, this._oldURI
);
758 function placesEditLivemarkFeedURITransactions(folderId
, uri
) {
759 this._folderId
= folderId
;
762 this.redoTransaction
= this.doTransaction
;
765 placesEditLivemarkFeedURITransactions
.prototype = {
766 __proto__
: placesBaseTransaction
.prototype,
768 doTransaction
: function PELFUT_doTransaction() {
769 this._oldURI
= PlacesUtils
.livemarks
.getFeedURI(this._folderId
);
770 PlacesUtils
.livemarks
.setFeedURI(this._folderId
, this._newURI
);
771 PlacesUtils
.livemarks
.reloadLivemarkFolder(this._folderId
);
774 undoTransaction
: function PELFUT_undoTransaction() {
775 PlacesUtils
.livemarks
.setFeedURI(this._folderId
, this._oldURI
);
776 PlacesUtils
.livemarks
.reloadLivemarkFolder(this._folderId
);
780 function placesEditBookmarkMicrosummaryTransactions(aID
, newMicrosummary
) {
782 this._mss
= Cc
["@mozilla.org/microsummary/service;1"].
783 getService(Ci
.nsIMicrosummaryService
);
784 this._newMicrosummary
= newMicrosummary
;
785 this._oldMicrosummary
= null;
786 this.redoTransaction
= this.doTransaction
;
789 placesEditBookmarkMicrosummaryTransactions
.prototype = {
790 __proto__
: placesBaseTransaction
.prototype,
792 doTransaction
: function PEBMT_doTransaction() {
793 this._oldMicrosummary
= this._mss
.getMicrosummary(this.id
);
794 if (this._newMicrosummary
)
795 this._mss
.setMicrosummary(this.id
, this._newMicrosummary
);
797 this._mss
.removeMicrosummary(this.id
);
800 undoTransaction
: function PEBMT_undoTransaction() {
801 if (this._oldMicrosummary
)
802 this._mss
.setMicrosummary(this.id
, this._oldMicrosummary
);
804 this._mss
.removeMicrosummary(this.id
);
808 function placesEditItemDateAddedTransaction(id
, newDateAdded
) {
810 this._newDateAdded
= newDateAdded
;
811 this._oldDateAdded
= null;
812 this.redoTransaction
= this.doTransaction
;
815 placesEditItemDateAddedTransaction
.prototype = {
816 __proto__
: placesBaseTransaction
.prototype,
818 // to support folders as well
819 get container() { return this.id
; },
820 set container(val
) { return this.id
= val
; },
822 doTransaction
: function PEIDA_doTransaction() {
823 this._oldDateAdded
= PlacesUtils
.bookmarks
.getItemDateAdded(this.id
);
824 PlacesUtils
.bookmarks
.setItemDateAdded(this.id
, this._newDateAdded
);
827 undoTransaction
: function PEIDA_undoTransaction() {
828 PlacesUtils
.bookmarks
.setItemDateAdded(this.id
, this._oldDateAdded
);
832 function placesEditItemLastModifiedTransaction(id
, newLastModified
) {
834 this._newLastModified
= newLastModified
;
835 this._oldLastModified
= null;
836 this.redoTransaction
= this.doTransaction
;
839 placesEditItemLastModifiedTransaction
.prototype = {
840 __proto__
: placesBaseTransaction
.prototype,
842 // to support folders as well
843 get container() { return this.id
; },
844 set container(val
) { return this.id
= val
; },
846 doTransaction
: function PEILM_doTransaction() {
847 this._oldLastModified
= PlacesUtils
.bookmarks
.getItemLastModified(this.id
);
848 PlacesUtils
.bookmarks
.setItemLastModified(this.id
, this._newLastModified
);
851 undoTransaction
: function PEILM_undoTransaction() {
852 PlacesUtils
.bookmarks
.setItemLastModified(this.id
, this._oldLastModified
);
856 function placesSortFolderByNameTransactions(aFolderId
) {
857 this._folderId
= aFolderId
;
858 this._oldOrder
= null,
859 this.redoTransaction
= this.doTransaction
;
862 placesSortFolderByNameTransactions
.prototype = {
863 __proto__
: placesBaseTransaction
.prototype,
865 doTransaction
: function PSSFBN_doTransaction() {
868 var contents
= PlacesUtils
.getFolderContents(this._folderId
, false, false).root
;
869 var count
= contents
.childCount
;
871 // sort between separators
873 var preSep
= []; // temporary array for sorting each group of items
876 if (PlacesUtils
.nodeIsContainer(a
) && !PlacesUtils
.nodeIsContainer(b
))
878 if (!PlacesUtils
.nodeIsContainer(a
) && PlacesUtils
.nodeIsContainer(b
))
880 return a
.title
.localeCompare(b
.title
);
883 for (var i
= 0; i
< count
; ++i
) {
884 var item
= contents
.getChild(i
);
885 this._oldOrder
[item
.itemId
] = i
;
886 if (PlacesUtils
.nodeIsSeparator(item
)) {
887 if (preSep
.length
> 0) {
888 preSep
.sort(sortingMethod
);
889 newOrder
= newOrder
.concat(preSep
);
897 if (preSep
.length
> 0) {
898 preSep
.sort(sortingMethod
);
899 newOrder
= newOrder
.concat(preSep
);
902 // set the nex indexes
904 runBatched: function() {
905 for (var i
= 0; i
< newOrder
.length
; ++i
) {
906 PlacesUtils
.bookmarks
.setItemIndex(newOrder
[i
].itemId
, i
);
910 PlacesUtils
.bookmarks
.runInBatchMode(callback
, null);
913 undoTransaction
: function PSSFBN_undoTransaction() {
916 runBatched: function() {
917 for (item
in this._self
._oldOrder
)
918 PlacesUtils
.bookmarks
.setItemIndex(item
, this._self
._oldOrder
[item
]);
921 PlacesUtils
.bookmarks
.runInBatchMode(callback
, null);
925 function placesTagURITransaction(aURI
, aTags
) {
928 this._unfiledItemId
= -1;
929 this.redoTransaction
= this.doTransaction
;
932 placesTagURITransaction
.prototype = {
933 __proto__
: placesBaseTransaction
.prototype,
935 doTransaction
: function PTU_doTransaction() {
936 if (PlacesUtils
.getMostRecentBookmarkForURI(this._uri
) == -1) {
937 // Force an unfiled bookmark first
938 this._unfiledItemId
=
939 PlacesUtils
.bookmarks
940 .insertBookmark(PlacesUtils
.unfiledBookmarksFolderId
,
942 PlacesUtils
.bookmarks
.DEFAULT_INDEX
,
943 PlacesUtils
.history
.getPageTitle(this._uri
));
945 PlacesUtils
.tagging
.tagURI(this._uri
, this._tags
);
948 undoTransaction
: function PTU_undoTransaction() {
949 if (this._unfiledItemId
!= -1) {
950 PlacesUtils
.bookmarks
.removeItem(this._unfiledItemId
);
951 this._unfiledItemId
= -1;
953 PlacesUtils
.tagging
.untagURI(this._uri
, this._tags
);
957 function placesUntagURITransaction(aURI
, aTags
) {
960 // Within this transaction, we cannot rely on tags given by itemId
961 // since the tag containers may be gone after we call untagURI.
962 // Thus, we convert each tag given by its itemId to name.
964 for (var i
=0; i
< aTags
.length
; i
++) {
965 if (typeof(this._tags
[i
]) == "number")
966 this._tags
[i
] = PlacesUtils
.bookmarks
.getItemTitle(this._tags
[i
]);
970 this._tags
= PlacesUtils
.tagging
.getTagsForURI(this._uri
, {});
972 this.redoTransaction
= this.doTransaction
;
975 placesUntagURITransaction
.prototype = {
976 __proto__
: placesBaseTransaction
.prototype,
978 doTransaction
: function PUTU_doTransaction() {
979 PlacesUtils
.tagging
.untagURI(this._uri
, this._tags
);
982 undoTransaction
: function PUTU_undoTransaction() {
983 PlacesUtils
.tagging
.tagURI(this._uri
, this._tags
);
988 function NSGetModule(aCompMgr
, aFileSpec
) {
989 return XPCOMUtils
.generateModule([placesTransactionsService
]);