home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / firefox-3.0.14 / chrome / browser.jar / content / browser / search / engineManager.js next >
Encoding:
Text File  |  2007-07-26  |  17.7 KB  |  550 lines

  1. //@line 40 "/build/buildd/firefox-3.0-3.0.14+build2+nobinonly/build-tree/mozilla/browser/components/search/content/engineManager.js"
  2.  
  3. const Ci = Components.interfaces;
  4. const Cc = Components.classes;
  5.  
  6. const ENGINE_FLAVOR = "text/x-moz-search-engine";
  7.  
  8. const BROWSER_SUGGEST_PREF = "browser.search.suggest.enabled";
  9.  
  10. var gEngineView = null;
  11.  
  12. var gEngineManagerDialog = {
  13.   init: function engineManager_init() {
  14.     gEngineView = new EngineView(new EngineStore());
  15.  
  16.     var prefService = Cc["@mozilla.org/preferences-service;1"].
  17.                       getService(Ci.nsIPrefBranch);
  18.     var suggestEnabled = prefService.getBoolPref(BROWSER_SUGGEST_PREF);
  19.     document.getElementById("enableSuggest").checked = suggestEnabled;
  20.  
  21.     var tree = document.getElementById("engineList");
  22.     tree.view = gEngineView;
  23.  
  24.     var os = Cc["@mozilla.org/observer-service;1"].
  25.              getService(Ci.nsIObserverService);
  26.     os.addObserver(this, "browser-search-engine-modified", false);
  27.   },
  28.  
  29.   observe: function engineManager_observe(aEngine, aTopic, aVerb) {
  30.     if (aTopic == "browser-search-engine-modified") {
  31.       aEngine.QueryInterface(Ci.nsISearchEngine)
  32.       switch (aVerb) {
  33.       case "engine-added":
  34.         gEngineView._engineStore.addEngine(aEngine);
  35.         gEngineView.rowCountChanged(gEngineView.lastIndex, 1);
  36.         break;
  37.       case "engine-changed":
  38.         gEngineView._engineStore.reloadIcons();
  39.         break;
  40.       case "engine-removed":
  41.       case "engine-current":
  42.         // Not relevant
  43.         return;
  44.       }
  45.       gEngineView.invalidate();
  46.     }
  47.   },
  48.  
  49.   onOK: function engineManager_onOK() {
  50.     // Remove the observer
  51.     var os = Cc["@mozilla.org/observer-service;1"].
  52.              getService(Ci.nsIObserverService);
  53.     os.removeObserver(this, "browser-search-engine-modified");
  54.  
  55.     // Set the preference
  56.     var newSuggestEnabled = document.getElementById("enableSuggest").checked;
  57.     var prefService = Cc["@mozilla.org/preferences-service;1"].
  58.                       getService(Ci.nsIPrefBranch);
  59.     prefService.setBoolPref(BROWSER_SUGGEST_PREF, newSuggestEnabled);
  60.  
  61.     // Commit the changes
  62.     gEngineView._engineStore.commit();
  63.   },
  64.   
  65.   onCancel: function engineManager_onCancel() {
  66.     // Remove the observer
  67.     var os = Cc["@mozilla.org/observer-service;1"].
  68.              getService(Ci.nsIObserverService);
  69.     os.removeObserver(this, "browser-search-engine-modified");
  70.   },
  71.  
  72.   onRestoreDefaults: function engineManager_onRestoreDefaults() {
  73.     var num = gEngineView._engineStore.restoreDefaultEngines();
  74.     gEngineView.rowCountChanged(0, num);
  75.     gEngineView.invalidate();
  76.   },
  77.  
  78.   showRestoreDefaults: function engineManager_showRestoreDefaults(val) {
  79.     document.documentElement.getButton("extra2").disabled = !val;
  80.   },
  81.  
  82.   loadAddEngines: function engineManager_loadAddEngines() {
  83.     this.onOK();
  84.     window.opener.BrowserSearch.loadAddEngines();
  85.     window.close();
  86.   },
  87.  
  88.   remove: function engineManager_remove() {
  89.     gEngineView._engineStore.removeEngine(gEngineView.selectedEngine);
  90.     var index = gEngineView.selectedIndex;
  91.     gEngineView.rowCountChanged(index, -1);
  92.     gEngineView.invalidate();
  93.     gEngineView.selection.select(Math.min(index, gEngineView.lastIndex));
  94.     gEngineView.ensureRowIsVisible(Math.min(index, gEngineView.lastIndex));
  95.     document.getElementById("engineList").focus();
  96.   },
  97.  
  98.   /**
  99.    * Moves the selected engine either up or down in the engine list
  100.    * @param aDir
  101.    *        -1 to move the selected engine down, +1 to move it up.
  102.    */
  103.   bump: function engineManager_move(aDir) {
  104.     var selectedEngine = gEngineView.selectedEngine;
  105.     var newIndex = gEngineView.selectedIndex - aDir;
  106.  
  107.     gEngineView._engineStore.moveEngine(selectedEngine, newIndex);
  108.  
  109.     gEngineView.invalidate();
  110.     gEngineView.selection.select(newIndex);
  111.     gEngineView.ensureRowIsVisible(newIndex);
  112.     this.showRestoreDefaults(true);
  113.     document.getElementById("engineList").focus();
  114.   },
  115.  
  116.   editKeyword: function engineManager_editKeyword() {
  117.     var selectedEngine = gEngineView.selectedEngine;
  118.     if (!selectedEngine)
  119.       return;
  120.  
  121.     var prompt = Cc["@mozilla.org/embedcomp/prompt-service;1"].
  122.                  getService(Ci.nsIPromptService);
  123.     var alias = { value: selectedEngine.alias };
  124.     var strings = document.getElementById("engineManagerBundle");
  125.     var title = strings.getString("editTitle");
  126.     var msg = strings.getFormattedString("editMsg", [selectedEngine.name]);
  127.  
  128.     while (prompt.prompt(window, title, msg, alias, null, { })) {
  129.       var bduplicate = false;
  130.       var eduplicate = false;
  131.  
  132.       if (alias.value != "") {
  133.         var searchService = Cc["@mozilla.org/browser/search-service;1"].
  134.                             getService(Ci.nsIBrowserSearchService);
  135.         var engine = searchService.getEngineByAlias(alias.value);
  136.  
  137.         if (engine) {
  138.           if (engine.name != selectedEngine.name)
  139.             eduplicate = true;
  140.         } else {
  141.           try {
  142.             var bmserv = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
  143.                          getService(Ci.nsINavBookmarksService);
  144.             if (bmserv.getURIForKeyword(alias.value))
  145.               bduplicate = true;
  146.           } catch(ex) {}
  147.  
  148.           // Check for duplicates in changes we haven't committed yet
  149.           var engines = gEngineView._engineStore.engines;
  150.           for each (var engine in engines) {
  151.             if (engine.alias == alias.value && 
  152.                 engine.name != selectedEngine.name) {
  153.               eduplicate = true;
  154.               break;
  155.             }
  156.           }
  157.         }
  158.       }
  159.  
  160.       // Notify the user if they have chosen an existing engine/bookmark keyword
  161.       if (eduplicate || bduplicate) {
  162.         var dtitle = strings.getString("duplicateTitle");
  163.         var bmsg = strings.getString("duplicateBookmarkMsg");
  164.         var emsg = strings.getFormattedString("duplicateEngineMsg",
  165.                                               [engine.name]);
  166.  
  167.         prompt.alert(window, dtitle, (eduplicate) ? emsg : bmsg);
  168.       } else {
  169.         gEngineView._engineStore.changeEngine(selectedEngine, "alias",
  170.                                               alias.value);
  171.         gEngineView.invalidate();
  172.         break;
  173.       }
  174.     }
  175.   },
  176.  
  177.   onSelect: function engineManager_onSelect() {
  178.     // buttons only work if an engine is selected and it's not the last engine
  179.     var disableButtons = (gEngineView.selectedIndex == -1) ||
  180.                          (gEngineView.lastIndex == 0);
  181.     var lastSelected = (gEngineView.selectedIndex == gEngineView.lastIndex);
  182.     var firstSelected = (gEngineView.selectedIndex == 0);
  183.     var noSelection = (gEngineView.selectedIndex == -1);
  184.  
  185.     document.getElementById("cmd_remove").setAttribute("disabled",
  186.                                                        disableButtons);
  187.  
  188.     document.getElementById("cmd_moveup").setAttribute("disabled",
  189.                                             disableButtons || firstSelected);
  190.  
  191.     document.getElementById("cmd_movedown").setAttribute("disabled",
  192.                                              disableButtons || lastSelected);
  193.     document.getElementById("cmd_editkeyword").setAttribute("disabled",
  194.                                                             noSelection);
  195.   }
  196. };
  197.  
  198. var gDragObserver = {
  199.   onDragStart: function (aEvent, aXferData, aDragAction) {
  200.     var selectedIndex = gEngineView.selectedIndex;
  201.     if (selectedIndex == -1)
  202.       return;
  203.  
  204.     aXferData.data = new TransferData();
  205.     aXferData.data.addDataForFlavour(ENGINE_FLAVOR, selectedIndex.toString());
  206.  
  207.     aDragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_MOVE;
  208.   },
  209.   onDrop: function (aEvent, aXferData, aDragSession) { },
  210.   onDragExit: function (aEvent, aDragSession) { },
  211.   onDragOver: function (aEvent, aFlavour, aDragSession) { },
  212.   getSupportedFlavours: function() { return null; }
  213. };
  214.  
  215. // "Operation" objects
  216. function EngineMoveOp(aEngineClone, aNewIndex) {
  217.   if (!aEngineClone)
  218.     throw new Error("bad args to new EngineMoveOp!");
  219.   this._engine = aEngineClone.originalEngine;
  220.   this._newIndex = aNewIndex;
  221. }
  222. EngineMoveOp.prototype = {
  223.   _engine: null,
  224.   _newIndex: null,
  225.   commit: function EMO_commit() {
  226.     var searchService = Cc["@mozilla.org/browser/search-service;1"].
  227.                         getService(Ci.nsIBrowserSearchService);
  228.     searchService.moveEngine(this._engine, this._newIndex);
  229.   }
  230. }
  231.  
  232. function EngineRemoveOp(aEngineClone) {
  233.   if (!aEngineClone)
  234.     throw new Error("bad args to new EngineRemoveOp!");
  235.   this._engine = aEngineClone.originalEngine;
  236. }
  237. EngineRemoveOp.prototype = {
  238.   _engine: null,
  239.   commit: function ERO_commit() {
  240.     var searchService = Cc["@mozilla.org/browser/search-service;1"].
  241.                         getService(Ci.nsIBrowserSearchService);
  242.     searchService.removeEngine(this._engine);
  243.   }
  244. }
  245.  
  246. function EngineUnhideOp(aEngineClone, aNewIndex) {
  247.   if (!aEngineClone)
  248.     throw new Error("bad args to new EngineUnhideOp!");
  249.   this._engine = aEngineClone.originalEngine;
  250.   this._newIndex = aNewIndex;
  251. }
  252. EngineUnhideOp.prototype = {
  253.   _engine: null,
  254.   _newIndex: null,
  255.   commit: function EUO_commit() {
  256.     this._engine.hidden = false;
  257.     var searchService = Cc["@mozilla.org/browser/search-service;1"].
  258.                         getService(Ci.nsIBrowserSearchService);
  259.     searchService.moveEngine(this._engine, this._newIndex);
  260.   }
  261. }
  262.  
  263. function EngineChangeOp(aEngineClone, aProp, aValue) {
  264.   if (!aEngineClone)
  265.     throw new Error("bad args to new EngineChangeOp!");
  266.  
  267.   this._engine = aEngineClone.originalEngine;
  268.   this._prop = aProp;
  269.   this._newValue = aValue;
  270. }
  271. EngineChangeOp.prototype = {
  272.   _engine: null,
  273.   _prop: null,
  274.   _newValue: null,
  275.   commit: function ECO_commit() {
  276.     this._engine[this._prop] = this._newValue;
  277.   }
  278. }
  279.  
  280. function EngineStore() {
  281.   var searchService = Cc["@mozilla.org/browser/search-service;1"].
  282.                       getService(Ci.nsIBrowserSearchService);
  283.   this._engines = searchService.getVisibleEngines({}).map(this._cloneEngine);
  284.   this._defaultEngines = searchService.getDefaultEngines({}).map(this._cloneEngine);
  285.  
  286.   this._ops = [];
  287.  
  288.   // check if we need to disable the restore defaults button
  289.   var someHidden = this._defaultEngines.some(function (e) {return e.hidden;});
  290.   gEngineManagerDialog.showRestoreDefaults(someHidden);
  291. }
  292. EngineStore.prototype = {
  293.   _engines: null,
  294.   _defaultEngines: null,
  295.   _ops: null,
  296.  
  297.   get engines() {
  298.     return this._engines;
  299.   },
  300.   set engines(val) {
  301.     this._engines = val;
  302.     return val;
  303.   },
  304.  
  305.   _getIndexForEngine: function ES_getIndexForEngine(aEngine) {
  306.     return this._engines.indexOf(aEngine);
  307.   },
  308.  
  309.   _getEngineByName: function ES_getEngineByName(aName) {
  310.     for each (var engine in this._engines)
  311.       if (engine.name == aName)
  312.         return engine;
  313.  
  314.     return null;
  315.   },
  316.  
  317.   _cloneEngine: function ES_cloneObj(aEngine) {
  318.     var newO=[];
  319.     for (var i in aEngine)
  320.       newO[i] = aEngine[i];
  321.     newO.originalEngine = aEngine;
  322.     return newO;
  323.   },
  324.  
  325.   // Callback for Array's some(). A thisObj must be passed to some()
  326.   _isSameEngine: function ES_isSameEngine(aEngineClone) {
  327.     return aEngineClone.originalEngine == this.originalEngine;
  328.   },
  329.  
  330.   commit: function ES_commit() {
  331.     var searchService = Cc["@mozilla.org/browser/search-service;1"].
  332.                         getService(Ci.nsIBrowserSearchService);
  333.     var currentEngine = this._cloneEngine(searchService.currentEngine);
  334.     for (var i = 0; i < this._ops.length; i++)
  335.       this._ops[i].commit();
  336.  
  337.     // Restore currentEngine if it is a default engine that is still visible.
  338.     // Needed if the user deletes currentEngine and then restores it.
  339.     if (this._defaultEngines.some(this._isSameEngine, currentEngine) &&
  340.         !currentEngine.originalEngine.hidden)
  341.       searchService.currentEngine = currentEngine.originalEngine;
  342.   },
  343.  
  344.   addEngine: function ES_addEngine(aEngine) {
  345.     this._engines.push(this._cloneEngine(aEngine));
  346.   },
  347.  
  348.   moveEngine: function ES_moveEngine(aEngine, aNewIndex) {
  349.     if (aNewIndex < 0 || aNewIndex > this._engines.length - 1)
  350.       throw new Error("ES_moveEngine: invalid aNewIndex!");
  351.     var index = this._getIndexForEngine(aEngine);
  352.     if (index == -1)
  353.       throw new Error("ES_moveEngine: invalid engine?");
  354.  
  355.     if (index == aNewIndex)
  356.       return; // nothing to do
  357.  
  358.     // Move the engine in our internal store
  359.     var removedEngine = this._engines.splice(index, 1)[0];
  360.     this._engines.splice(aNewIndex, 0, removedEngine);
  361.  
  362.     this._ops.push(new EngineMoveOp(aEngine, aNewIndex));
  363.   },
  364.  
  365.   removeEngine: function ES_removeEngine(aEngine) {
  366.     var index = this._getIndexForEngine(aEngine);
  367.     if (index == -1)
  368.       throw new Error("invalid engine?");
  369.  
  370.     this._engines.splice(index, 1);
  371.     this._ops.push(new EngineRemoveOp(aEngine));
  372.     if (this._defaultEngines.some(this._isSameEngine, aEngine))
  373.       gEngineManagerDialog.showRestoreDefaults(true);
  374.   },
  375.  
  376.   restoreDefaultEngines: function ES_restoreDefaultEngines() {
  377.     var added = 0;
  378.  
  379.     for (var i = 0; i < this._defaultEngines.length; ++i) {
  380.       var e = this._defaultEngines[i];
  381.  
  382.       // If the engine is already in the list, just move it.
  383.       if (this._engines.some(this._isSameEngine, e)) {
  384.         this.moveEngine(this._getEngineByName(e.name), i);
  385.       } else {
  386.         // Otherwise, add it back to our internal store
  387.         this._engines.splice(i, 0, e);
  388.         this._ops.push(new EngineUnhideOp(e, i));
  389.         added++;
  390.       }
  391.     }
  392.     gEngineManagerDialog.showRestoreDefaults(false);
  393.     return added;
  394.   },
  395.  
  396.   changeEngine: function ES_changeEngine(aEngine, aProp, aNewValue) {
  397.     var index = this._getIndexForEngine(aEngine);
  398.     if (index == -1)
  399.       throw new Error("invalid engine?");
  400.  
  401.     this._engines[index][aProp] = aNewValue;
  402.     this._ops.push(new EngineChangeOp(aEngine, aProp, aNewValue));
  403.   },
  404.  
  405.   reloadIcons: function ES_reloadIcons() {
  406.     this._engines.forEach(function (e) {
  407.       e.uri = e.originalEngine.uri;
  408.     });
  409.   }
  410. }
  411.  
  412. function EngineView(aEngineStore) {
  413.   this._engineStore = aEngineStore;
  414. }
  415. EngineView.prototype = {
  416.   _engineStore: null,
  417.   tree: null,
  418.  
  419.   get lastIndex() {
  420.     return this.rowCount - 1;
  421.   },
  422.   get selectedIndex() {
  423.     var seln = this.selection;
  424.     if (seln.getRangeCount() > 0) {
  425.       var min = { };
  426.       seln.getRangeAt(0, min, { });
  427.       return min.value;
  428.     }
  429.     return -1;
  430.   },
  431.   get selectedEngine() {
  432.     return this._engineStore.engines[this.selectedIndex];
  433.   },
  434.  
  435.   // Helpers
  436.   rowCountChanged: function (index, count) {
  437.     this.tree.rowCountChanged(index, count);
  438.   },
  439.  
  440.   invalidate: function () {
  441.     this.tree.invalidate();
  442.   },
  443.  
  444.   ensureRowIsVisible: function (index) {
  445.     this.tree.ensureRowIsVisible(index);
  446.   },
  447.  
  448.   getSourceIndexFromDrag: function () {
  449.     var dragService = Cc["@mozilla.org/widget/dragservice;1"].
  450.                       getService().QueryInterface(Ci.nsIDragService);
  451.     var dragSession = dragService.getCurrentSession();
  452.     var transfer = Cc["@mozilla.org/widget/transferable;1"].
  453.                    createInstance(Ci.nsITransferable);
  454.  
  455.     transfer.addDataFlavor(ENGINE_FLAVOR);
  456.     dragSession.getData(transfer, 0);
  457.  
  458.     var dataObj = {};
  459.     var len = {};
  460.     var sourceIndex = -1;
  461.     try {
  462.       transfer.getAnyTransferData({}, dataObj, len);
  463.     } catch (ex) {}
  464.  
  465.     if (dataObj.value) {
  466.       sourceIndex = dataObj.value.QueryInterface(Ci.nsISupportsString).data;
  467.       sourceIndex = parseInt(sourceIndex.substring(0, len.value));
  468.     }
  469.  
  470.     return sourceIndex;
  471.   },
  472.  
  473.   // nsITreeView
  474.   get rowCount() {
  475.     return this._engineStore.engines.length;
  476.   },
  477.  
  478.   getImageSrc: function(index, column) {
  479.     if (column.id == "engineName" && this._engineStore.engines[index].iconURI)
  480.       return this._engineStore.engines[index].iconURI.spec;
  481.     return "";
  482.   },
  483.  
  484.   getCellText: function(index, column) {
  485.     if (column.id == "engineName")
  486.       return this._engineStore.engines[index].name;
  487.     else if (column.id == "engineKeyword")
  488.       return this._engineStore.engines[index].alias;
  489.     return "";
  490.   },
  491.  
  492.   setTree: function(tree) {
  493.     this.tree = tree;
  494.   },
  495.  
  496.   canDrop: function(targetIndex, orientation) {
  497.     var sourceIndex = this.getSourceIndexFromDrag();
  498.     return (sourceIndex != -1 &&
  499.             sourceIndex != targetIndex &&
  500.             sourceIndex != (targetIndex + orientation));
  501.   },
  502.  
  503.   drop: function(dropIndex, orientation) {
  504.     var sourceIndex = this.getSourceIndexFromDrag();
  505.     var sourceEngine = this._engineStore.engines[sourceIndex];
  506.  
  507.     if (dropIndex > sourceIndex) {
  508.       if (orientation == Ci.nsITreeView.DROP_BEFORE)
  509.         dropIndex--;
  510.     } else {
  511.       if (orientation == Ci.nsITreeView.DROP_AFTER)
  512.         dropIndex++;    
  513.     }
  514.  
  515.     this._engineStore.moveEngine(sourceEngine, dropIndex);
  516.     gEngineManagerDialog.showRestoreDefaults(true);
  517.  
  518.     // Redraw, and adjust selection
  519.     this.invalidate();
  520.     this.selection.clearSelection();
  521.     this.selection.select(dropIndex);
  522.   },
  523.  
  524.   selection: null,
  525.   getRowProperties: function(index, properties) { },
  526.   getCellProperties: function(index, column, properties) { },
  527.   getColumnProperties: function(column, properties) { },
  528.   isContainer: function(index) { return false; },
  529.   isContainerOpen: function(index) { return false; },
  530.   isContainerEmpty: function(index) { return false; },
  531.   isSeparator: function(index) { return false; },
  532.   isSorted: function(index) { return false; },
  533.   getParentIndex: function(index) { return -1; },
  534.   hasNextSibling: function(parentIndex, index) { return false; },
  535.   getLevel: function(index) { return 0; },
  536.   getProgressMode: function(index, column) { },
  537.   getCellValue: function(index, column) { },
  538.   toggleOpenState: function(index) { },
  539.   cycleHeader: function(column) { },
  540.   selectionChanged: function() { },
  541.   cycleCell: function(row, column) { },
  542.   isEditable: function(index, column) { return false; },
  543.   isSelectable: function(index, column) { return false; },
  544.   setCellValue: function(index, column, value) { },
  545.   setCellText: function(index, column, value) { },
  546.   performAction: function(action) { },
  547.   performActionOnRow: function(action, index) { },
  548.   performActionOnCell: function(action, index, column) { }
  549. };
  550.