Bug 448909 - Need more controls WHATWG Video tag. r=mconnor, r=bz
[wine-gecko.git] / browser / components / places / src / nsPlacesTransactionsService.js
blob947ff5715be762b95d7e06b38b9de0ad432a8285
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
13 * License.
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.
22 * Contributor(s):
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
53 var tmpScope = {};
54 Components.utils.import("resource://gre/modules/utils.js", tmpScope);
55 return this.PlacesUtils = tmpScope.PlacesUtils;
56 });
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",
69 classID: CLASS_ID,
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);
184 if (win)
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() {
240 return this;
243 // nsITransaction
244 redoTransaction: function PBT_redoTransaction() {
245 throw Cr.NS_ERROR_NOT_IMPLEMENTED;
248 get isTransient() {
249 return false;
252 merge: function mergeFunc(transaction) {
253 return false;
256 // nsISupports
257 QueryInterface: XPCOMUtils.generateQI([Ci.nsITransaction]),
260 function placesAggregateTransactions(name, transactions) {
261 this._transactions = transactions;
262 this._name = name;
263 this.container = -1;
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) {
272 var callback = {
273 _self: this,
274 runBatched: function() {
275 this._self.commit(false);
278 PlacesUtils.bookmarks.runInBatchMode(callback, null);
280 else
281 this.commit(false);
284 undoTransaction: function PAT_undoTransaction() {
285 if (this._transactions.length >= MIN_TRANSACTIONS_FOR_BATCH) {
286 var callback = {
287 _self: this,
288 runBatched: function() {
289 this._self.commit(true);
292 PlacesUtils.bookmarks.runInBatchMode(callback, null);
294 else
295 this.commit(true);
298 commit: function PAT_commit(aUndo) {
299 var transactions = this._transactions;
300 if (aUndo)
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;
306 if (aUndo)
307 txn.undoTransaction();
308 else
309 txn.doTransaction();
314 function placesCreateFolderTransactions(aName, aContainer, aIndex,
315 aAnnotations,
316 aChildItemsTransactions) {
317 this._name = aName;
318 this._container = aContainer;
319 this._index = typeof(aIndex) == "number" ? aIndex : -1;
320 this._annotations = aAnnotations;
321 this._id = null;
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;
342 txn.doTransaction();
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) {
358 this._uri = aURI;
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);
378 if (this._keyword)
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;
386 txn.doTransaction();
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;
402 this._id = null;
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,
424 aContainer, aIndex,
425 aAnnotations) {
426 this._feedURI = aFeedURI;
427 this._siteURI = aSiteURI;
428 this._name = aName;
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,
444 this._index);
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) {
455 this._id = aItemId;
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);
477 else
478 PlacesUtils.bookmarks.moveItem(this._id, this._oldContainer, this._oldIndex);
482 function placesRemoveItemTransaction(aItemId) {
483 this.redoTransaction = this.doTransaction;
484 this._id = aItemId;
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();
514 else {
515 if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK)
516 this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._id);
517 PlacesUtils.bookmarks.removeItem(this._id);
518 if (this._uri) {
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,
533 this._uri,
534 this._oldIndex,
535 this._title);
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 = [];
561 var contents =
562 PlacesUtils.getFolderContents(this._id, false, false).root;
563 for (var i = 0; i < contents.childCount; ++i) {
564 this._transactions
565 .push(new placesRemoveItemTransaction(contents.getChild(i).itemId));
570 function placesEditItemTitleTransactions(id, newTitle) {
571 this._id = id;
572 this._newTitle = newTitle;
573 this._oldTitle = "";
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,
633 _anno: {
634 name: loadInSidebarAnno,
635 type: Ci.nsIAnnotationService.TYPE_INT32,
636 value: 1,
637 flags: 0,
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]);
646 else {
647 try {
648 PlacesUtils.annotations.removeItemAnnotation(this.id, this._anno.name);
649 } catch(ex) { }
653 undoTransaction: function PSLIST_undoTransaction() {
654 if (this._wasSet != this._loadInSidebar) {
655 this._loadInSidebar = !this._loadInSidebar;
656 this.doTransaction();
661 function placesEditItemDescriptionTransactions(aItemId, aDescription) {
662 this.id = aItemId;
663 this._newDescription = aDescription;
664 this.redoTransaction = this.doTransaction;
667 placesEditItemDescriptionTransactions.prototype = {
668 __proto__: placesBaseTransaction.prototype,
670 _oldDescription: "",
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,
680 annos.EXPIRE_NEVER);
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,
691 annos.EXPIRE_NEVER);
693 else if (annos.itemHasAnnotation(this.id, descriptionAnno))
694 annos.removeItemAnnotation(this.id, descriptionAnno);
698 function placesEditBookmarkKeywordTransactions(id, newKeyword) {
699 this.id = id;
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) {
719 this.id = aItemId;
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;
740 this._newURI = uri;
741 this._oldURI = null;
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;
760 this._newURI = uri;
761 this._oldURI = null;
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) {
781 this.id = aID;
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);
796 else
797 this._mss.removeMicrosummary(this.id);
800 undoTransaction: function PEBMT_undoTransaction() {
801 if (this._oldMicrosummary)
802 this._mss.setMicrosummary(this.id, this._oldMicrosummary);
803 else
804 this._mss.removeMicrosummary(this.id);
808 function placesEditItemDateAddedTransaction(id, newDateAdded) {
809 this.id = id;
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) {
833 this.id = id;
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() {
866 this._oldOrder = [];
868 var contents = PlacesUtils.getFolderContents(this._folderId, false, false).root;
869 var count = contents.childCount;
871 // sort between separators
872 var newOrder = [];
873 var preSep = []; // temporary array for sorting each group of items
874 var sortingMethod =
875 function (a, b) {
876 if (PlacesUtils.nodeIsContainer(a) && !PlacesUtils.nodeIsContainer(b))
877 return -1;
878 if (!PlacesUtils.nodeIsContainer(a) && PlacesUtils.nodeIsContainer(b))
879 return 1;
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);
890 preSep.splice(0);
892 newOrder.push(item);
894 else
895 preSep.push(item);
897 if (preSep.length > 0) {
898 preSep.sort(sortingMethod);
899 newOrder = newOrder.concat(preSep);
902 // set the nex indexes
903 var callback = {
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() {
914 var callback = {
915 _self: this,
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) {
926 this._uri = aURI;
927 this._tags = 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,
941 this._uri,
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) {
958 this._uri = aURI;
959 if (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.
963 this._tags = aTags;
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]);
969 else
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]);