home *** CD-ROM | disk | FTP | other *** search
/ PC Advisor 2005 August / PCADVD_121.iso / internet / nsb-setup.exe / chrome / inspector.jar / content / inspector / search / inSearchService.js < prev    next >
Encoding:
JavaScript  |  2004-11-25  |  11.8 KB  |  419 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Netscape Public License
  5.  * Version 1.1 (the "License"); you may not use this file except in
  6.  * compliance with the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/NPL/
  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 mozilla.org code.
  15.  *
  16.  * The Initial Developer of the Original Code is 
  17.  * Netscape Communications Corporation.
  18.  * Portions created by the Initial Developer are Copyright (C) 2001
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *   Joe Hewitt <hewitt@netscape.com> (original author)
  23.  *
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the NPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the NPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. /***************************************************************
  40. * inSearchService -----------------------------------------------
  41. *  The centry registry where information about all installed
  42. *  search modules is kept.  
  43. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  44. * Until Bug 54237 is fixed, there be some ugly hacks in this 
  45. * file.  We'll need to load search modules via a XUL document
  46. * within an iframe, instead of using the xml loader for now.
  47. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  48. * REQUIRED IMPORTS:
  49. *   chrome://inspector/content/jsutil/xpcom/XPCU.js
  50. *   chrome://inspector/content/search/inSearchTreeBuilder.js
  51. *   chrome://inspector/content/search/inSearchModule.js
  52. ****************************************************************/
  53.  
  54. //////////// global variables /////////////////////
  55.  
  56. //////////// global constants ////////////////////
  57.  
  58. var kSearchURLPrefix = "chrome://inspector/content/search/";
  59.  
  60. ////////////////////////////////////////////////////////////////////////////
  61. //// class inSearchService
  62.  
  63. function inSearchService() 
  64. {
  65.   this.mInstances = {};
  66.   this.mObservers = [];
  67.   
  68.   // the browser and webnav are a hack.  We should be able to use 
  69.   // the xmlextras facility for loading xml, but it's broken, so 
  70.   // we use a browser for onw
  71.   var browser = document.getElementById("inSearchServiceLoader");
  72.   browser.addEventListener("load", inSearchService_LoadListener, true);
  73.   this.mWebNav = browser.webNavigation;
  74. }
  75.  
  76. // constants
  77. inSearchService.INSERT_BEFORE = 1;
  78. inSearchService.INSERT_AFTER = 2;
  79.  
  80. inSearchService.prototype = 
  81. {
  82.   mInstances: null,
  83.   mObservers: null,
  84.   mCurrentModule: null,
  85.   
  86.   mTree: null,
  87.   mContextMenu: null,
  88.   mCMInsertPt: null,
  89.   mCMInsert: inSearchService.INSERT_BEFORE,
  90.   
  91.   ////////////////////////////////////////////////////////////////////////////
  92.   //// Properties
  93.   
  94.   get currentModule() { return this.mCurrentModule },
  95.  
  96.   get resultsTree() { return this.mTree },
  97.   set resultsTree(aTree) {
  98.     // XX this condition could be fixed with a little bit of effort
  99.     if (this.mTree) throw "inSearchService.tree should only be set once"
  100.     
  101.     this.mTree = aTree;
  102.     aTree._searchService = this;
  103.  
  104.     this.mTreeBuilder = new inSearchTreeBuilder(aTree, kInspectorNSURI, "results");
  105.     this.mTreeBuilder.isIconic = true;
  106.  
  107.     // XX HACKERY AT IT'S FINEST - the click event won't fire when I add it to the tree -- go figure
  108.     // in the mean time I'll add it to the parentNode, which seems to work. FIX ME!
  109.     var parent = aTree.parentNode;
  110.     parent._tempTreeYuckyHack = aTree;
  111.     parent.addEventListener("click", inSearchService_TreeClickListener, false);
  112.   },
  113.  
  114.   get contextMenu() { return this.mContextMenu },
  115.   set contextMenu(aVal) 
  116.   { 
  117.     this.mContextMenu = aVal;
  118.     aVal._searchService = this;
  119.   },
  120.   
  121.   get contextMenuInsertPt() { return this.mCMInsertPt },
  122.   set contextMenuInsertPt(aVal) { this.mCMInsertPt = aVal },
  123.   
  124.   get contextMenuInsert() { return this.mCMInsert },
  125.   set contextMenuInsert(aVal) { this.mCMInsert = aVal },
  126.   
  127.   ////////////////////////////////////////////////////////////////////////////
  128.   //// Running Modules
  129.  
  130.   startModule: function(aURL)
  131.   {
  132.     var instance = this.mInstances[aURL];
  133.     if (instance)
  134.       this.doStartModule(instance);
  135.     else
  136.       this.loadModule(aURL);
  137.   },
  138.   
  139.   doStartModule: function(aModule)
  140.   {
  141.     aModule.startSearch();
  142.   },
  143.  
  144.   startSearch: function(aModule)
  145.   { 
  146.     this.mCurrentModule = aModule;
  147.     
  148.     // build up the context menu
  149.     this.installContextMenu();
  150.     
  151.     // build up the search results tree
  152.     this.mTreeBuilder.module = aModule;
  153.   },    
  154.  
  155.   clearSearch: function()
  156.   {
  157.     var mod = this.mCurrentModule;
  158.     if (mod) {
  159.       // clear datasource from search tree
  160.       this.mTreeBuilder.module = null;
  161.       this.mTreeBuilder.buildContent();
  162.       
  163.       // clear context menu
  164.       this.uninstallContextMenu();
  165.     } 
  166.  
  167.     this.mCurrentModule = null;
  168.   },
  169.  
  170.   ////////////////////////////////////////////////////////////////////////////
  171.   //// Loading Modules
  172.  
  173.   loadModule: function(aURL)
  174.   {
  175.     this.mWebNav.loadURI(aURL, nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
  176.     this.mLoadingURL = aURL;
  177.     /* 
  178.     // This method of loading the xml doesn't work, but it should.  See bug 54237... 
  179.     var doc = document.implementation.createDocument("", "", null);
  180.     doc.addEventListener("load", SearchFileLoadListener, false);
  181.     doc.load(aURL, "text/xml");
  182.     */ 
  183.   },
  184.   
  185.   searchFileLoaded: function()
  186.   {
  187.     var mod = this.createModule(this.mWebNav.document);
  188.     mod.addSearchObserver(this);
  189.     this.mInstances[this.mLoadingURL] = mod;
  190.     this.doStartModule(mod);
  191.   },
  192.   
  193.   createModule: function(aDocument)
  194.   {
  195.     var mod = new inSearchModule(aDocument.location);
  196.     mod.searchService = this;
  197.     mod.initFromElement(aDocument.documentElement);
  198.     
  199.     return mod;    
  200.   },
  201.   
  202.   ////////////////////////////////////////////////////////////////////////////
  203.   //// interface inISearchObserver
  204.  
  205.   onSearchStart: function(aModule) 
  206.   {
  207.     this.startSearch(aModule);
  208.     this.notifySearchStart();
  209.   },
  210.  
  211.   onSearchResult: function(aModule)
  212.   {
  213.     this.notifySearchResult();
  214.   },
  215.  
  216.   onSearchEnd: function(aModule, aResult)
  217.   {
  218.     this.notifySearchEnd(aResult);
  219.   },
  220.  
  221.   onSearchError: function(aModule, aMessage)
  222.   {
  223.     this.notifySearchError(aMessage);
  224.     this.clearSearch();
  225.   },
  226.  
  227.   ////////////////////////////////////////////////////////////////////////////
  228.   //// Results Tree
  229.  
  230.   get selectedItemCount()
  231.   {
  232.     return this.mTree ? this.mTree.selectedItems.length : null;
  233.   },
  234.   
  235.   getSelectedIndex: function(aIdx)
  236.   {
  237.     if (this.mTree) {
  238.       var items = this.mTree.selectedItems;
  239.       return this.mTree.getIndexOfItem(items[aIdx]);
  240.     }
  241.     return null;
  242.   },
  243.   
  244.   onTreeDblClick: function()
  245.   {
  246.     this.mCurrentModule.callDefaultCommand();
  247.   },
  248.  
  249.   //////////////////////////////////////////////////////////////////////////
  250.   //// ContextMenu
  251.  
  252.   installContextMenu: function()
  253.   {
  254.     var mod = this.mCurrentModule;
  255.     if (mod) {
  256.       var menu = this.mContextMenu;
  257.       menu.addEventListener("popupshowing", inSearchService_onCreatePopup, true);
  258.       mod.installContextMenu(menu, this.mCMInsertPt, this.mCMInsert);
  259.     }
  260.   },
  261.   
  262.   uninstallContextMenu: function()
  263.   {
  264.     var mod = this.mCurrentModule;
  265.     if (mod) {
  266.       // remove the createion listener
  267.       var menu = this.mContextMenu;
  268.       menu.removeEventListener("popupshowing", inSearchService_onCreatePopup, true);
  269.       mod.uninstallContextMenu(menu, this.mCMInsertPt, this.mCMInsert);
  270.     }
  271.   },
  272.  
  273.   onCreatePopup: function(aMenu)
  274.   {
  275.     
  276.   },
  277.   
  278.   //////////////////////////////////////////////////////////////////////////
  279.   //// Event Notification
  280.   
  281.   // NOTE TO SELF - this code could be cut down to nothing if you write a module
  282.   // called "ObserverManager" to do the work for you
  283.   
  284.   addSearchObserver: function(aObserver)
  285.   {
  286.     this.mObservers.push(aObserver);
  287.   },
  288.   
  289.   removeSearchObserver: function(aObserver)
  290.   {
  291.     var o;
  292.     var obs = this.mObservers;
  293.     for (var i = 0; i < obs.length; i++) {
  294.       o = obs[i];
  295.       if (o == aObserver) {
  296.         obs.splice(i, 1);
  297.         return;
  298.       }
  299.     }
  300.   },
  301.  
  302.   notifySearchStart: function()
  303.   {
  304.     var o = this.mObservers;
  305.     for (var i = 0; i < o.length; i++)
  306.       o[i].onSearchStart(this.mCurrentModule);
  307.   },
  308.   
  309.   notifySearchResult: function()
  310.   {
  311.     var o = this.mObservers;
  312.     for (var i = 0; i < o.length; i++)
  313.       o[i].onSearchResult(this.mCurrentModule);
  314.   },
  315.  
  316.   notifySearchEnd: function(aResult)
  317.   {
  318.     var o = this.mObservers;
  319.     for (var i = 0; i < o.length; i++)
  320.       o[i].onSearchEnd(this.mCurrentModule, aResult);
  321.   },
  322.  
  323.   notifySearchError: function(aMsg)
  324.   {
  325.     var o = this.mObservers;
  326.     for (var i = 0; i < o.length; i++)
  327.       o[i].onSearchError(this.mCurrentModule, aMsg);
  328.   }
  329.   
  330. };
  331.  
  332. ////////////////////////////////////////////////////////////////////////////
  333. //// Event Listeners
  334.  
  335. function inSearchService_LoadListener(aEvent)
  336. {
  337.   inspector.searchRegistry.searchFileLoaded();
  338. }
  339.  
  340. function inSearchService_TreeClickListener(aEvent)
  341. {
  342.   if (aEvent.detail == 2) {
  343.     var tree = this._tempTreeYuckyHack;
  344.     tree._searchService.onTreeDblClick();
  345.   }
  346. }
  347.  
  348. function inSearchService_onCreatePopup(aEvent)
  349. {
  350.   // event.target is returning null for this event - I should file a bug
  351.   // in the mean time I'll just back off this feature for now...
  352.   
  353. /*  var menu = aEvent.target;
  354.   var svc = menu._searchService;
  355.   svc.onCreatePopup(menu);
  356. */
  357. }
  358.  
  359. // This code is from when there was an RDF "search registry"... I might want to bring that back,
  360. // so I'll keep this code sitting here for a little while...
  361.  
  362. /*
  363. function inSearchServiceLoadObserver(aTarget) 
  364. {
  365.   this.mTarget = aTarget;
  366. }
  367.  
  368. inSearchServiceLoadObserver.prototype = {
  369.   mTarget: null,
  370.  
  371.   onError: function(aErrorMsg) 
  372.   {
  373.     this.mTarget.onLoadError(aErrorMsg);
  374.   },
  375.  
  376.   onDataSourceReady: function(aDS) 
  377.   {
  378.     this.mTarget.onLoad(aDS);
  379.   }
  380. };
  381.  
  382.   load: function(aURL, aObserver)
  383.   {
  384.     this.mURL = aURL;
  385.     this.mObserver = aObserver;
  386.     RDFU.loadDataSource(aURL, new inSearchServiceLoadObserver(this));
  387.   },
  388.  
  389.   onLoad: function(aDS)
  390.   {
  391.     this.mDS = aDS;
  392.     this.prepareRegistry();
  393.     this.mObserver.oninSearchServiceLoad();
  394.   },
  395.  
  396.   onLoadError: function(aErrorMsg)
  397.   {
  398.     this.mObserver.oninSearchServiceLoadError(aErrorMsg);
  399.   },
  400.  
  401.   prepareRegistry: function()
  402.   {
  403.     this.mModuleSeq = RDFU.findSeq(this.mDS, "inspector:search");
  404.  
  405.     var el, uid, fnName, factory;
  406.     var els = this.mModuleSeq.GetElements();
  407.     while (els.hasMoreElements()) {
  408.       el = els.getNext();
  409.       uid = RDFU.readAttribute(this.mDS, el, kInspectorNSURI+"uid");
  410.       fnName = RDFU.readAttribute(this.mDS, el, kInspectorNSURI+"factory");
  411.       factory = eval(fnName);
  412.       if (factory)
  413.         this.mFactories[uid] = factory;
  414.     }
  415.  
  416.   },
  417.   */
  418.  
  419.