home *** CD-ROM | disk | FTP | other *** search
/ Minami 83 / MINAMI83.iso / Extra / DivXInstaller.exe / $PLUGINSDIR / GoogleToolbarFirefox.msi / xpi / components / gtbComponent.js < prev    next >
Text File  |  2006-08-07  |  18KB  |  592 lines

  1. const Cc = Components.classes;
  2. const Ci = Components.interfaces;
  3. const Cr = Components.results;
  4. const HTTP_OK                    = 200;
  5. const HTTP_INTERNAL_SERVER_ERROR = 500;
  6. const HTTP_BAD_GATEWAY           = 502;
  7. const HTTP_SERVICE_UNAVAILABLE   = 503;
  8. var nsIComponentRegistrar = Ci.nsIComponentRegistrar;
  9. var UNINSTALLER_CID = Components.ID("{abf0defb-ad5c-4673-a8fe-edd64c22a441}");
  10. var UNINSTALLER_NAME = "Google Toolbar Uninstall Handler";
  11. var UNINSTALLER_CONTRACTID = "@google.com/uninstaller;1";
  12. function GTB_UninstallExtension(guid) {
  13. try {
  14. var manager = Cc["@mozilla.org/extensions/manager;1"]
  15. .getService(Ci.nsIExtensionManager);
  16. var dummy = manager.datasource;  // HACK: force datasource initialization
  17. if ("uninstallExtension" in manager) {
  18. manager.uninstallExtension('{' + guid + '}');
  19. } else if ("uninstallItem" in manager) {
  20. manager.uninstallItem('{' + guid + '}');
  21. } else {
  22. return false;
  23. }
  24. dummy = null;  // REHACK: don't leak any resources
  25. }
  26. catch(e) {
  27. }
  28. return true;
  29. }
  30. function insertCommas(number) {
  31. var s = number.toString();
  32. var result = "";
  33. while(s.length > 3) {
  34. result = "," + s.substring(s.length-3, s.length);
  35. s = s.substring(0, s.length-3);
  36. }
  37. result = s + result;
  38. return result;
  39. }
  40. var SEARCH_SUGGEST_CONTRACTID = "@mozilla.org/autocomplete/search;1?name=google-search-suggest";
  41. var SEARCH_SUGGEST_CLASSNAME = "Google Search Suggest";
  42. var SEARCH_SUGGEST_CLASSID = Components.ID("{71631a52-b676-4628-8831-f777932b82ec}");
  43. var SEARCH_SUGGEST_SERVICEURL = "google.suggest.serviceURL.search";
  44. var USERAGENT_LOCALE_PREF = "general.useragent.locale";
  45. function SuggestAutoCompleteResult(searchString,
  46. searchResult,
  47. defaultIndex,
  48. errorDescription,
  49. suggestResults,
  50. suggestComments,
  51. historyResults,
  52. historyComments) {
  53. this._searchString = searchString;
  54. this._searchResult = searchResult;
  55. this._defaultIndex = defaultIndex;
  56. this._errorDescription = errorDescription;
  57. for (var i in historyResults) {
  58. for (var j in suggestResults) {
  59. if (historyResults[i] == suggestResults[j]) {
  60. suggestResults.splice(j, 1);
  61. suggestComments.splice(j, 1);
  62. break;
  63. }
  64. }
  65. }
  66. var results = [];
  67. results = results.concat(historyResults);
  68. results = results.concat(suggestResults);
  69. this._results = results;
  70. var comments = [];
  71. comments = comments.concat(historyComments);
  72. comments = comments.concat(suggestComments);
  73. this._comments = comments;
  74. }
  75. SuggestAutoCompleteResult.prototype = {
  76. _resultString: "",
  77. _resultsString: "",
  78. _didYouMeanString: "",
  79. _historyString: "",
  80. _searchString: "",
  81. _searchResult: 0,
  82. _defaultIndex: 0,
  83. _errorDescription: "",
  84. _results: [],
  85. _comments: [],
  86. getValueAt: function(index) {
  87. return this._results[index];
  88. },
  89. getCommentAt: function(index) {
  90. return this._comments[index];
  91. },
  92. getStyleAt: function(index) {
  93. return null;
  94. },
  95. removeValueAt: function(index, removeFromDatabase) {
  96. this._results.splice(index, 1);
  97. this._comments.splice(index, 1);
  98. },
  99. QueryInterface: function(iid) {
  100. if (!iid.equals(Ci.nsIAutoCompleteResult) &&
  101. !iid.equals(Ci.nsISupports)) {
  102. throw Cr.NS_ERROR_NO_INTERFACE;
  103. }
  104. return this;
  105. }
  106. };
  107. SuggestAutoCompleteResult.prototype.__defineGetter__("searchString", function() {
  108. return this._searchString;
  109. });
  110. SuggestAutoCompleteResult.prototype.__defineGetter__("searchResult", function() {
  111. return this._searchResult;
  112. });
  113. SuggestAutoCompleteResult.prototype.__defineGetter__("defaultIndex", function() {
  114. return this._defaultIndex;
  115. });
  116. SuggestAutoCompleteResult.prototype.__defineGetter__("errorDescription", function() {
  117. return this._errorDescription;
  118. });
  119. SuggestAutoCompleteResult.prototype.__defineGetter__("matchCount", function() {
  120. return this._results.length;
  121. });
  122. function SuggestAutoComplete() { }
  123. SuggestAutoComplete.prototype = {
  124. _serverErrorLog: [],
  125. _maxErrorsBeforeBackoff: 3,
  126. _serverErrorPeriod: 600000,  // 10 minutes in milliseconds
  127. _serverErrorTimeoutIncrement: 600000,  // 10 minutes in milliseconds
  128. _serverErrorTimeout: 0,
  129. _nextRequestTime: 0,
  130. _serverErrorURI: null,
  131. _requestSuggest: null,
  132. _listener: null,
  133. onSuggestReadyStateChange: function() {
  134. if (!this._requestSuggest || this._requestSuggest.readyState != 4)
  135. return;
  136. try {
  137. var status = this._requestSuggest.status;
  138. } catch (e) {
  139. }
  140. var suggestResults = [];
  141. var suggestComments = [];
  142. var spellingResults = [];
  143. var spellingComments = [];
  144. var responseText = this._requestSuggest.responseText;
  145. if (status == HTTP_OK && responseText != "") {
  146. this._clearServerErrors();
  147. var parser = Cc["@mozilla.org/xmlextras/domparser;1"]
  148. .createInstance(Ci.nsIDOMParser);
  149. var xmlDoc = parser.parseFromString(responseText, "text/xml");
  150. if (xmlDoc != null) {
  151. var topLevelNode = xmlDoc.documentElement;
  152. if (topLevelNode.hasChildNodes()) {
  153. var children = topLevelNode.childNodes;
  154. for (var i = 0 ; i < children.length; i++) {
  155. var child = children[i];
  156. if (child.nodeName == "CompleteSuggestion" &&
  157. child.hasChildNodes()) {
  158. var suggestionText = null;
  159. var resultCount = null;
  160. var suggestion = child.childNodes;
  161. for(var j=0 ; j < suggestion.length ; j++) {
  162. if (suggestion[j].nodeName == "suggestion") {
  163. suggestionText = suggestion[j].getAttribute("data");
  164. } else if (suggestion[j].nodeName == "num_queries") {
  165. resultCount = parseInt(suggestion[j].getAttribute("int"));
  166. }
  167. }
  168. if (suggestionText != null && resultCount != null) {
  169. suggestResults[suggestResults.length] = suggestionText;
  170. suggestComments[suggestComments.length] =
  171. insertCommas(resultCount) + " " +
  172. (resultCount == 1 ?
  173. this._resultString :
  174. this._resultsString);
  175. }
  176. } else if (child.nodeName == "spelling_suggestion") {
  177. var spellingText = child.getAttribute("data");
  178. spellingText = spellingText.replace(/<\/{0,1}[a-z]+\/{0,1}>/gi,"");
  179. spellingResults[spellingResults.length] = spellingText;
  180. spellingComments[spellingComments.length] = this._didYouMeanString;
  181. }
  182. }
  183. }
  184. }
  185. } else if (this._isBackoffError(status)) {
  186. this._noteServerError();
  187. }
  188. var results = [];
  189. var comments = [];
  190. results = results.concat(spellingResults);
  191. results = results.concat(suggestResults);
  192. comments = comments.concat(spellingComments);
  193. comments = comments.concat(suggestComments);
  194. this.onSuggestResultsReady(this._searchString, results, comments);
  195. this._requestSuggest = null;
  196. },
  197. onSuggestResultsReady: function(searchString, results, comments) {
  198. if (this._listener) {
  199. this._suggestResults = results;
  200. this._suggestComments = comments;
  201. if (this._suggestResults != null  && this._suggestComments != null &&
  202. this._historyResults != null  && this._historyComments != null) {
  203. var result = new SuggestAutoCompleteResult(searchString,
  204. Ci.nsIAutoCompleteResult.RESULT_SUCCESS,
  205. 0, "",
  206. this._suggestResults, this._suggestComments,
  207. this._historyResults, this._historyComments);
  208. this._listener.onSearchResult(this, result);
  209. }
  210. }
  211. },
  212. onSuggestError: function() {
  213. if (this._listener) {
  214. this._suggestResults = [];
  215. this._suggestComments = [];
  216. if (this._suggestResults != null  && this._suggestComments != null &&
  217. this._historyResults != null  && this._historyComments != null) {
  218. var result = new SuggestAutoCompleteResult("",
  219. Ci.nsIAutoCompleteResult.RESULT_FAILURE,
  220. 0, "",
  221. this._suggestResults, this._suggestComments,
  222. this._historyResults, this._historyComments);
  223. this._listener.onSearchResult(this, result);
  224. }
  225. }
  226. },
  227. startSearch: function(searchString, searchParam, previousResult, listener) {
  228. if (this._requestSuggest) {
  229. this.stopSuggestSearch();
  230. }
  231. this._historyResults = null;
  232. this._historyComments = null;
  233. this._suggestResults = null;
  234. this._suggestComments = null;
  235. this._listener = listener;
  236. this._searchString = searchString;
  237. if (searchString && this._okToRequest()) {
  238. this._requestSuggest = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
  239. .createInstance(Ci.nsIXMLHttpRequest);
  240. this._requestSuggest.open("GET", this.serviceURL + searchString, true);
  241. var self = this;
  242. function onSuggestReadyStateChange() {
  243. self.onSuggestReadyStateChange();
  244. }
  245. function onSuggestError() {
  246. self.onSuggestError();
  247. }
  248. this._requestSuggest.onreadystatechange = onSuggestReadyStateChange;
  249. this._requestSuggest.onerror = onSuggestError;
  250. this._requestSuggest.send(null);
  251. }
  252. var history = getMatchingHistory(this._searchString);
  253. this._historyResults = [];
  254. this._historyComments = [];
  255. for(var j=0 ; j < history.length ; j++) {
  256. this._historyResults[this._historyResults.length] = history[j];
  257. this._historyComments[this._historyComments.length] = this._historyString;
  258. }
  259. },
  260. stopSuggestSearch: function() {
  261. if (this._requestSuggest) {
  262. this._requestSuggest.abort();
  263. this._requestSuggest = null;
  264. }
  265. },
  266. stopSearch: function() {
  267. this.stopSuggestSearch();
  268. this._listener = null;
  269. },
  270. _noteServerError: function SAC__noteServeError() {
  271. var currentTime = Date.now();
  272. this._serverErrorLog.push(currentTime);
  273. if (this._serverErrorLog.length > this._maxErrorsBeforeBackoff)
  274. this._serverErrorLog.shift();
  275. if ((this._serverErrorLog.length == this._maxErrorsBeforeBackoff) &&
  276. ((currentTime - this._serverErrorLog[0]) < this._serverErrorPeriod)) {
  277. this._serverErrorTimeout = (this._serverErrorTimeout * 2) +
  278. this._serverErrorTimeoutIncrement;
  279. this._nextRequestTime = currentTime + this._serverErrorTimeout;
  280. }
  281. },
  282. _clearServerErrors: function SAC__clearServerErrors() {
  283. this._serverErrorLog = [];
  284. this._serverErrorTimeout = 0;
  285. this._nextRequestTime = 0;
  286. },
  287. _okToRequest: function SAC__okToRequest() {
  288. return Date.now() > this._nextRequestTime;
  289. },
  290. _isBackoffError: function SAC__isBackoffError(status) {
  291. return ((status == HTTP_INTERNAL_SERVER_ERROR) ||
  292. (status == HTTP_BAD_GATEWAY) ||
  293. (status == HTTP_SERVICE_UNAVAILABLE));
  294. },
  295. QueryInterface: function(iid) {
  296. if (!iid.equals(Ci.nsIAutoCompleteSearch) &&
  297. !iid.equals(Ci.nsIAutoCompleteObserver) &&
  298. !iid.equals(Ci.nsISupports)) {
  299. throw Cr.NS_ERROR_NO_INTERFACE;
  300. }
  301. return this;
  302. }
  303. };
  304. function getMatchingHistory(query) {
  305. var psvc = Cc["@mozilla.org/preferences;1"]
  306. .getService(Ci.nsIPrefBranch);
  307. var result = [];
  308. if (psvc != null) {
  309. var pref = psvc.getComplexValue("google.toolbar.search_box_history",
  310. Ci.nsISupportsString).data;
  311. if (pref != null) {
  312. var temp = pref.split("\n");
  313. for(var i=0 ; i < temp.length ; i++) {
  314. if(temp[i].indexOf(query) == 0) {
  315. result[result.length] = temp[i];
  316. }
  317. }
  318. }
  319. }
  320. return result;
  321. }
  322. function getServiceURL(serviceURLPref) {
  323. var psvc = Cc["@mozilla.org/preferences;1"]
  324. .getService(Ci.nsIPrefBranch);
  325. var locale = psvc.getCharPref(USERAGENT_LOCALE_PREF);
  326. var langCode = locale;
  327. if (langCode.length > 2) {
  328. langCode = langCode.substr(0, langCode.indexOf("-"));
  329. }
  330. if (langCode == "nb") {
  331. langCode = "no";
  332. }
  333. var serviceURL = "http://toolbarqueries.google.com/complete/search?hl=%LANG%&client=firetools&output=toolbar&q=";
  334. return serviceURL.replace(/%LANG%/, langCode);
  335. }
  336. function SearchSuggestAutoComplete() {
  337. this.serviceURL = getServiceURL(SEARCH_SUGGEST_SERVICEURL);
  338. var bundle_service = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
  339. var stringBundle = bundle_service.createBundle("chrome://google-toolbar/locale/google-toolbar.properties");
  340. if(stringBundle){
  341. this._resultString = stringBundle.GetStringFromName("google-suggest.result");
  342. this._resultsString = stringBundle.GetStringFromName("google-suggest.results");
  343. this._didYouMeanString = stringBundle.GetStringFromName("google-suggest.didyoumean");
  344. this._historyString = stringBundle.GetStringFromName("google-suggest.history");
  345. }
  346. }
  347. SearchSuggestAutoComplete.prototype = {
  348. __proto__: SuggestAutoComplete.prototype,
  349. serviceURL: ""
  350. };
  351. function GetProperty(datasource, item, prop) {
  352. var service = Cc["@mozilla.org/rdf/rdf-service;1"]
  353. .getService(Ci.nsIRDFService);
  354. var resource = service.GetResource("http://www.mozilla.org/2004/em-rdf#" + prop);
  355. var valueNode = datasource.GetTarget(item, resource, true);
  356. if (valueNode) {
  357. if (valueNode instanceof Ci.nsIRDFLiteral)
  358. return valueNode.Value;
  359. else if (valueNode instanceof Ci.nsIRDFResource)
  360. return valueNode.Value
  361. }
  362. return null;
  363. }
  364. var gModule = {
  365. _firstTime: true,
  366. getClassObject: function(compMgr, cid, iid) {
  367. if (!iid.equals(Ci.nsIFactory))
  368. throw Cr.NS_ERROR_NOT_IMPLEMENTED;
  369. for (var key in this.objects) {
  370. if (cid.equals(this.objects[key].CID)){
  371. return this.objects[key].factory;
  372. }
  373. }
  374. if (!cid.equals(UNINSTALLER_CID)) {
  375. throw Cr.NS_ERROR_NO_INTERFACE;
  376. }
  377. return this.uninstallerFactory;
  378. },
  379. registerSelf: function(compMgr, location, loaderStr, type) {
  380. compMgr.QueryInterface(nsIComponentRegistrar);
  381. if (this._firstTime) {
  382. compMgr.registerFactoryLocation(
  383. UNINSTALLER_CID,
  384. UNINSTALLER_NAME,
  385. UNINSTALLER_CONTRACTID,
  386. location, loaderStr, type);
  387. this._firstTime = false;
  388. throw Cr.NS_ERROR_FACTORY_REGISTER_AGAIN;
  389. }
  390. for (var key in this.objects) {
  391. var obj = this.objects[key];
  392. compMgr.registerFactoryLocation(obj.CID, obj.className, obj.contractID,
  393. location, loaderStr, type);
  394. }
  395. },
  396. _makeFactory: function(constructor) {
  397. function createInstance(outer, iid) {
  398. if (outer != null)
  399. throw Cr.NS_ERROR_NO_AGGREGATION;
  400. return (new constructor()).QueryInterface(iid);
  401. }
  402. return { createInstance: createInstance };
  403. },
  404. canUnload: function(compMgr) {
  405. return true;
  406. },
  407. QueryInterface: function(iid) {
  408. if (iid.equals(Ci.nsIModule) ||
  409. iid.equals(Ci.nsISupports))
  410. return this;
  411. throw Cr.NS_ERROR_NO_INTERFACE;
  412. },
  413. uninstallerFactory: {
  414. QueryInterface: function(iid) {
  415. if (iid.equals(Ci.nsIFactory) ||
  416. iid.equals(Ci.nsISupports))
  417. return this;
  418. throw Cr.NS_ERROR_NO_INTERFACE;
  419. },
  420. createInstance: function(outer, iid) {
  421. if (outer != null) {
  422. throw Cr.NS_ERROR_NO_AGGREGATION;
  423. }
  424. if (!this.uninstaller) {
  425. this.uninstaller = {
  426. updateVersion: function() {
  427. try {
  428. var RDF = Cc["@mozilla.org/rdf/rdf-service;1"]
  429. .getService(Ci.nsIRDFService);
  430. var datasource = Cc["@mozilla.org/extensions/manager;1"]
  431. .getService(Ci.nsIExtensionManager).datasource;
  432. var property = RDF.GetResource("http://www.mozilla.org/2004/em-rdf#version");
  433. var resource = RDF.GetResource("urn:mozilla:item:{3112ca9c-de6d-4884-a869-9855de68056c}");
  434. var target = datasource.GetTarget(resource, property, true);
  435. if (target == null) {
  436. resource = RDF.GetResource("urn:mozilla:extension:{3112ca9c-de6d-4884-a869-9855de68056c}");
  437. target = datasource.GetTarget(resource, property, true);
  438. }
  439. var version = null;
  440. if (target instanceof Ci.nsIRDFLiteral) {
  441. version = target.Value;
  442. version = version.replace(/[WML]/g, "");
  443. }
  444. try {
  445. var regClass = Cc["@google.com/regutil;1"];
  446. if (regClass) {
  447. var regUtil = regClass.createInstance(Ci.GTBIRegUtil);
  448. if (regUtil) {
  449. var key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{2CCBABCB-6427-4A55-B091-49864623C43F}";
  450. var result = regUtil.setLocalMachineString(
  451. key,
  452. "DisplayVersion",
  453. version);
  454. var versionParts = version.split('.');
  455. result = regUtil.setLocalMachineDword(
  456. key,
  457. "VersionMajor",
  458. versionParts[0]);
  459. result = regUtil.setLocalMachineDword(
  460. key,
  461. "VersionMinor",
  462. versionParts[1]);
  463. result = regUtil.setLocalMachineDword(
  464. key,
  465. "Version",
  466. versionParts[2]);
  467. }
  468. }
  469. } catch (e) {
  470. }
  471. } catch (e) {
  472. }
  473. },
  474. handleUninstall: function() {
  475. var prefService = Cc["@mozilla.org/preferences;1"]
  476. .getService(Ci.nsIPrefService);
  477. var prefBranch = prefService.getBranch('google.toolbar.');
  478. prefBranch.deleteBranch('');
  479. try {
  480. var regClass = Cc["@google.com/regutil;1"];
  481. if (regClass) {
  482. var regUtil = regClass.createInstance(Ci.GTBIRegUtil);
  483. if (regUtil) {
  484. var result = regUtil.deleteLocalMachineString("SOFTWARE\\Google\\Toolbar for Firefox", "id");
  485. }
  486. }
  487. } catch (e) {
  488. }
  489. try {
  490. prefService.savePrefFile(null);
  491. } catch (e) {
  492. dump('Error saving pref file:' + e);
  493. }
  494. },
  495. observe: function(subject, topic, data) {
  496. var GUID = '3112ca9c-de6d-4884-a869-9855de68056c';
  497. if (topic == "em-action-requested" && data == "item-uninstalled") {
  498. var item = subject.QueryInterface(Ci.nsIUpdateItem);
  499. var id = item.id.toLowerCase();
  500. if (id == "{" + GUID + "}") {
  501. var prefService = Cc["@mozilla.org/preferences;1"]
  502. .getService(Ci.nsIPrefService);
  503. var prefBranch = prefService.getBranch('google.toolbar.');
  504. prefBranch.setBoolPref("uninstall_pending", true);
  505. }
  506. }
  507. if (topic == "xpcom-shutdown") {
  508. var prefService = Cc["@mozilla.org/preferences;1"]
  509. .getService(Ci.nsIPrefService);
  510. var prefBranch = prefService.getBranch('google.toolbar.');
  511. if (prefBranch.prefHasUserValue("uninstall_pending")) {
  512. this.handleUninstall();
  513. return;
  514. }
  515. var service = Cc["@mozilla.org/rdf/rdf-service;1"]
  516. .getService(Ci.nsIRDFService);
  517. var container = Cc["@mozilla.org/rdf/container;1"]
  518. .createInstance(Ci.nsIRDFContainer);
  519. var datasource= Cc["@mozilla.org/extensions/manager;1"]
  520. .getService(Ci.nsIExtensionManager).datasource;
  521. var rootName = "urn:mozilla:extension:"
  522. var root = service.GetResource(rootName + "root");
  523. var nameResource = service
  524. .GetResource("http://www.mozilla.org/2004/em-rdf#name");
  525. var uninstallResource = service
  526. .GetResource("http://www.mozilla.org/2004/em-rdf#toBeUninstalled");
  527. var disableResource = service
  528. .GetResource("http://www.mozilla.org/2004/em-rdf#toBeDisabled");
  529. try {
  530. container.Init(datasource, root);
  531. } catch (e) {
  532. rootName = "urn:mozilla:item:";
  533. root = service.GetResource(rootName + "root");
  534. container.Init(datasource, root);
  535. }
  536. var elements = container.GetElements();
  537. while (elements.hasMoreElements()) {
  538. var elt = elements.getNext()
  539. .QueryInterface(Ci.nsIRDFResource);
  540. if (elt.Value != rootName + "{" + GUID + "}") {
  541. continue;
  542. }
  543. var found = false;
  544. var values = ["toBeUninstalled", "toBeDisabled"]; //, "userDisabled"];
  545. for (var i = 0, value = null; value = values[i]; ++i) {
  546. var rdfValue = GetProperty(datasource, elt, value);
  547. if ("true" == rdfValue) {
  548. found = true;
  549. }
  550. }
  551. var rdfValue = GetProperty(datasource, elt, "opType");
  552. if ("needs-uninstall" == rdfValue) {
  553. found = true;
  554. }
  555. if (found) {
  556. this.handleUninstall();
  557. GTB_UninstallExtension(GUID);
  558. }
  559. }
  560. }
  561. },
  562. QueryInterface: function(iid) {
  563. if (iid.equals(Ci.nsISupports) ||
  564. iid.equals(Ci.nsIObserver)) {
  565. return this;
  566. }
  567. throw Cr.NS_ERROR_NO_INTERFACE;
  568. }
  569. };
  570. this.uninstaller.updateVersion();
  571. var obs = Cc["@mozilla.org/observer-service;1"]
  572. .getService(Ci.nsIObserverService);
  573. obs.addObserver(this.uninstaller, "xpcom-shutdown", false);
  574. obs.addObserver(this.uninstaller, "em-action-requested", false);
  575. }
  576. return this.uninstaller.QueryInterface(iid);
  577. },
  578. uninstaller: null
  579. }
  580. };
  581. function NSGetModule(compMgr, location) {
  582. gModule.objects = {
  583. search: {
  584. CID: SEARCH_SUGGEST_CLASSID,
  585. contractID: SEARCH_SUGGEST_CONTRACTID,
  586. className: SEARCH_SUGGEST_CLASSNAME,
  587. factory: gModule._makeFactory(SearchSuggestAutoComplete)
  588. }
  589. };
  590. return gModule;
  591. }
  592.