home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / firefox / components / nsBookmarkTransactionManager.js < prev    next >
Encoding:
JavaScript  |  2006-06-28  |  13.3 KB  |  374 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is bookmark transaction code.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  *   Joey Minta <jminta@gmail.com>
  18.  *
  19.  * Portions created by the Initial Developer are Copyright (C) 2006
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK ***** */
  37.  
  38. function bookmarkTransactionManager() {
  39.     this.wrappedJSObject = this;
  40.     this.mTransactionManager = Components.classes["@mozilla.org/transactionmanager;1"]
  41.                                          .createInstance(Components.interfaces.nsITransactionManager);
  42.  
  43.     this.mBatchCount = 0;
  44.  
  45.     this.classInfo = {
  46.         getInterfaces: function (count) {
  47.             var ifaces = [
  48.                 Components.interfaces.nsISupports,
  49.                 Components.interfaces.nsIClassInfo
  50.             ];
  51.             count.value = ifaces.length;
  52.             return ifaces;
  53.         },
  54.  
  55.         getHelperForLanguage: function (language) {
  56.             return null;
  57.         },
  58.  
  59.         contractID: "@mozilla.org/bookmarks/transactionManager;1",
  60.         classDescription: "Booksmarks Transaction Manager",
  61.         classID: Components.ID("{62d2f7fb-acd2-4876-aa2d-b607de9329ff}"),
  62.         implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
  63.         flags: 0
  64.     };
  65.  
  66.     // Define our transactions
  67.     function bkmkTxn() {
  68.         this.item    = null;
  69.         this.parent  = null;
  70.         this.index   = null;
  71.         this.removedProp = null;
  72.     };
  73.  
  74.     bkmkTxn.prototype = {
  75.         BMDS: null,
  76.  
  77.         QueryInterface: function bkmkTxnQI(iid) {
  78.             if (!iid.equals(Components.interfaces.nsITransaction) &&
  79.                 !iid.equals(Components.interfaces.nsISupports))
  80.             throw Components.results.NS_ERROR_NO_INTERFACE;
  81.  
  82.             return this;
  83.         },
  84.  
  85.         merge               : function (aTxn)   {return false},
  86.         getHelperForLanguage: function (aCount) {return null},
  87.         getInterfaces       : function (aCount) {return null},
  88.         canCreateWrapper    : function (aIID)   {return "AllAccess"},
  89.  
  90.         mAssertProperties: function bkmkTxnAssertProps(aProps) {
  91.             if (!aProps) {
  92.                 return;
  93.             }
  94.  
  95.             for each (var prop in aProps) {
  96.                 for (var i = 0; i < this.Properties.length; i++) {
  97.                     var oldValue = this.BMDS.GetTarget(this.item, this.Properties[i], true);
  98.                     // must check, if paste call after copy the oldvalue didn't remove.
  99.                     if (!oldValue) {
  100.                         var newValue = aProps[i];
  101.                         if (newValue) {
  102.                             this.BMDS.Assert(this.item, 
  103.                                              this.Properties[i], 
  104.                                              newValue, true);
  105.                         }
  106.                     } else {
  107.                         this.removedProp[i] = oldValue;
  108.                     }
  109.                 }
  110.             }
  111.         },
  112.  
  113.         mUnassertProperties: function bkmkTxnUnassertProps(aProps) {
  114.             if (!aProps) {
  115.                 return;
  116.             }
  117.             for each (var prop in aProps) {
  118.                 for (var i = 0; i < this.Properties.length; i++) {
  119.                     var oldValue = aProps[i];
  120.                     if (oldValue) {
  121.                         this.BMDS.Unassert(this.item, this.Properties[i], oldValue);
  122.                     }
  123.                 }
  124.             }
  125.         }
  126.     };
  127.  
  128.     bkmkTxn.prototype.RDFC = 
  129.             Components.classes["@mozilla.org/rdf/container;1"]
  130.                       .createInstance(Components.interfaces.nsIRDFContainer);
  131.     var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"]
  132.                                .getService(Components.interfaces.nsIRDFService);
  133.     bkmkTxn.prototype.BMDS = rdfService.GetDataSource("rdf:bookmarks");
  134.  
  135.     bkmkTxn.prototype.Properties = 
  136.             [rdfService.GetResource("http://home.netscape.com/NC-rdf#Name"),
  137.              rdfService.GetResource("http://home.netscape.com/NC-rdf#URL"),
  138.              rdfService.GetResource("http://home.netscape.com/NC-rdf#ShortcutURL"),
  139.              rdfService.GetResource("http://home.netscape.com/NC-rdf#Description"),
  140.              rdfService.GetResource("http://home.netscape.com/NC-rdf#WebPanel"),
  141.              rdfService.GetResource("http://home.netscape.com/NC-rdf#FeedURL")];
  142.  
  143.     function bkmkInsertTxn(aAction) {
  144.         this.type = "insert";
  145.         // move container declaration to here so it can be recognized if
  146.         // undoTransaction is call after the BM manager is close and reopen.
  147.         this.container = Components.classes["@mozilla.org/rdf/container;1"]
  148.                                    .createInstance(Components.interfaces.nsIRDFContainer);
  149.     }
  150.  
  151.     bkmkInsertTxn.prototype = {
  152.          __proto__: bkmkTxn.prototype,
  153.  
  154.          isTransient: false,
  155.  
  156.          doTransaction: function bkmkInsertDoTxn() {
  157.              this.RDFC.Init(this.BMDS, this.parent);
  158.              // if the index is -1, we use appendElement, and then update the
  159.              // index so that undoTransaction can still function
  160.              if (this.index == -1) {
  161.                  this.RDFC.AppendElement(this.item);
  162.                  this.index = this.RDFC.GetCount();
  163.              } else {
  164. /*XXX- broken insert code, see bug 264571
  165.                  try {
  166.                      this.RDFC.InsertElementAt(this.item, this.index, true);
  167.                  } catch (e if e.result == Components.results.NS_ERROR_ILLEGAL_VALUE) {
  168.                      // if this failed, then we assume that we really want to append,
  169.                      // because things are out of whack until we renumber.
  170.                      this.RDFC.AppendElement(this.item);
  171.                      // and then fix up the index so undo works
  172.                      this.index = this.RDFC.GetCount();
  173.                  }
  174. */
  175.                  this.RDFC.InsertElementAt(this.item, this.index, true);
  176.              }
  177.  
  178.              // insert back all the properties
  179.              this.mAssertProperties(this.removedProp);
  180.          },
  181.  
  182.          undoTransaction: function bkmkInsertUndoTxn() {
  183.              // XXXvarga Can't use |RDFC| here because it's being "reused" elsewhere.
  184.              this.container.Init(this.BMDS, this.parent);
  185.  
  186.              // remove all properties befor we remove the element so
  187.              // nsLocalSearchService doesn't return deleted element in Search
  188.              this.mUnassertProperties(this.removedProp);
  189.  
  190.              this.container.RemoveElementAt(this.index, true);
  191.          },
  192.  
  193.          redoTransaction: function bkmkInsertRedoTxn() {
  194.              this.doTransaction();
  195.          }
  196.     };
  197.  
  198.     function bkmkRemoveTxn() {
  199.         this.type    = "remove";
  200.     }
  201.  
  202.     bkmkRemoveTxn.prototype = {
  203.         __proto__: bkmkTxn.prototype,
  204.  
  205.         isTransient: false,
  206.  
  207.         doTransaction: function bkmkRemoveDoTxn() {
  208.             this.RDFC.Init(this.BMDS, this.parent);
  209.  
  210.             // remove all properties befor we remove the element so
  211.             // nsLocalSearchService doesn't return deleted element in Search
  212.             this.mUnassertProperties(this.removedProp);
  213.  
  214.             this.RDFC.RemoveElementAt(this.index, false);
  215.         },
  216.  
  217.         undoTransaction: function bkmkRemoveUndoTxn() {
  218.             this.RDFC.Init(this.BMDS, this.parent);
  219.             this.RDFC.InsertElementAt(this.item, this.index, false);
  220.  
  221.             // insert back all the properties
  222.             this.mAssertProperties(this.removedProp);
  223.         },
  224.  
  225.         redoTransaction: function () {
  226.             this.doTransaction();
  227.         }
  228.     }
  229.  
  230.     function bkmkImportTxn(aAction) {
  231.         this.type    = "import";
  232.         this.action  = aAction;
  233.     }
  234.  
  235.     bkmkImportTxn.prototype = {
  236.         __proto__: bkmkTxn.prototype,
  237.  
  238.         isTransient: false,
  239.  
  240.         doTransaction: function bkmkImportDoTxn() {},
  241.  
  242.         undoTransaction: function mkmkImportUndoTxn() {
  243.             this.RDFC.Init(this.BMDS, this.parent);
  244.             this.RDFC.RemoveElementAt(this.index, true);
  245.         },
  246.  
  247.         redoTransaction: function bkmkImportredoTxn() {
  248.             this.RDFC.Init(this.BMDS, this.parent);
  249.             this.RDFC.InsertElementAt(this.item, this.index, true);
  250.         }
  251.     };
  252.  
  253.     this.BookmarkRemoveTransaction = bkmkRemoveTxn;
  254.     this.BookmarkInsertTransaction = bkmkInsertTxn;
  255.     this.BookmarkImportTransaction = bkmkImportTxn;
  256. }
  257.  
  258. bookmarkTransactionManager.prototype.QueryInterface = function bkTxnMgrQI(aIID) {
  259.     if (aIID.equals(Components.interfaces.nsISupports) ||
  260.         aIID.equals(Components.interfaces.nsIBookmarkTransactionManager)) {
  261.         return this;
  262.     } 
  263.     if (aIID.equals(Components.interfaces.nsIClassInfo)) {
  264.         return this.classInfo;
  265.     }
  266.  
  267.     throw NS_ERROR_NO_INTERFACE;
  268. }
  269.  
  270. bookmarkTransactionManager.prototype.createAndCommitTxn = 
  271. function bkmkTxnMgrCandC(aType, aAction, aItem, aIndex, aParent, aPropCount, aRemovedProps) {
  272.     var txn;
  273.     var nsIBookmarkTransactionManager = Components.interfaces.nsIBookmarkTransactionManager;
  274.     switch (aType) {
  275.         case nsIBookmarkTransactionManager.IMPORT: 
  276.             txn = new this.BookmarkImportTransaction(aAction);
  277.             break;
  278.         case nsIBookmarkTransactionManager.INSERT: 
  279.             txn = new this.BookmarkInsertTransaction(aAction);
  280.             break;
  281.         case nsIBookmarkTransactionManager.REMOVE: 
  282.             txn = new this.BookmarkRemoveTransaction(aAction);
  283.             break;
  284.         default:
  285.             Components.utils.reportError("Unknown bookmark transaction type:"+aType);
  286.             throw NS_ERROR_FAILURE;
  287.     }
  288.     txn.item = aItem;
  289.     txn.parent = aParent;
  290.     txn.index = aIndex;
  291.     txn.removedProp = aRemovedProps;
  292.     txn.action = aAction;
  293.     txn.wrappedJSObject = txn;
  294.     this.mTransactionManager.doTransaction(txn);
  295. }
  296.  
  297. bookmarkTransactionManager.prototype.startBatch = function bkmkTxnMgrUndo() {
  298.     if (this.mBatchCount == 0) {
  299.         this.mTransactionManager.beginBatch();
  300.     }
  301.     this.mBatchCount++;
  302. }
  303.  
  304. bookmarkTransactionManager.prototype.endBatch = function bkmkTxnMgrUndo() {
  305.     this.mBatchCount--;
  306.     if (this.mBatchCount == 0) {
  307.         this.mTransactionManager.endBatch();
  308.     }
  309. }
  310.  
  311. bookmarkTransactionManager.prototype.undo = function bkmkTxnMgrUndo() {
  312.     this.mTransactionManager.undoTransaction();
  313. }
  314.  
  315. bookmarkTransactionManager.prototype.redo = function bkmkTxnMgrRedo() {
  316.     this.mTransactionManager.redoTransaction();
  317. }
  318.  
  319. bookmarkTransactionManager.prototype.canUndo = function bkmkTxnMgrCanUndo() {
  320.     return this.mTransactionManager.numberOfUndoItems > 0;
  321. }
  322.  
  323. bookmarkTransactionManager.prototype.canRedo = function bkmkTxnMgrCanRedo() {
  324.     return this.mTransactionManager.numberOfRedoItems > 0;
  325. }
  326.  
  327. bookmarkTransactionManager.prototype.__defineGetter__("transactionManager", 
  328. function bkmkTxnMgrGetter() {  return this.mTransactionManager; });
  329.  
  330. /****
  331.  **** module registration
  332.  ****/
  333.  
  334. const kFactory = {
  335.     createInstance: function (outer, iid) {
  336.         if (outer != null)
  337.             throw Components.results.NS_ERROR_NO_AGGREGATION;
  338.         return (new bookmarkTransactionManager()).QueryInterface(iid);
  339.     }
  340. };
  341.  
  342. var bkmkTxnMgrModule = {
  343.     mCID: Components.ID("{8be133d0-681d-4f0b-972b-6a68e41afb62}"),
  344.     mContractID: "@mozilla.org/bookmarks/transactionmanager;1",
  345.     
  346.     registerSelf: function (compMgr, fileSpec, location, type) {
  347.         compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  348.         compMgr.registerFactoryLocation(this.mCID,
  349.                                         "Bookmark Transaction Manager",
  350.                                         this.mContractID,
  351.                                         fileSpec,
  352.                                         location,
  353.                                         type);
  354.     },
  355.  
  356.     getClassObject: function (compMgr, cid, iid) {
  357.         if (!cid.equals(this.mCID))
  358.             throw Components.results.NS_ERROR_NO_INTERFACE;
  359.  
  360.         if (!iid.equals(Components.interfaces.nsIFactory))
  361.             throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  362.  
  363.         return kFactory;
  364.     },
  365.  
  366.     canUnload: function(compMgr) {
  367.         return true;
  368.     }
  369. };
  370.  
  371. function NSGetModule(compMgr, fileSpec) {
  372.     return bkmkTxnMgrModule;
  373. }
  374.