michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: michael@0: this.EXPORTED_SYMBOLS = [ "AutoCompleteE10S" ]; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: // nsITreeView implementation that feeds the autocomplete popup michael@0: // with the search data. michael@0: let AutoCompleteE10SView = { michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsITreeView, michael@0: Ci.nsIAutoCompleteController]), michael@0: treeBox: null, michael@0: selection: null, michael@0: treeData: [], michael@0: michael@0: get rowCount() { return this.treeData.length; }, michael@0: setTree: function(treeBox) { this.treeBox = treeBox; }, michael@0: getCellText: function(idx, column) { return this.treeData[idx] }, michael@0: isContainer: function(idx) { return false; }, michael@0: getCellValue: function(idx, column){ return false }, michael@0: isContainerOpen: function(idx) { return false; }, michael@0: isContainerEmpty: function(idx) { return false; }, michael@0: isSeparator: function(idx) { return false; }, michael@0: isSorted: function() { return false; }, michael@0: isEditable: function(idx, column) { return false; }, michael@0: canDrop: function(idx, orientation, dt) { return false; }, michael@0: getLevel: function(idx) { return 0; }, michael@0: getParentIndex: function(idx) { return -1; }, michael@0: hasNextSibling: function(idx, after) { return idx < this.treeData.length - 1 }, michael@0: toggleOpenState: function(idx) { }, michael@0: getCellProperties: function(idx, column) { return ""; }, michael@0: getRowProperties: function(idx) { return ""; }, michael@0: getImageSrc: function(idx, column) { return null; }, michael@0: getProgressMode : function(idx, column) { }, michael@0: cycleHeader: function(column) { }, michael@0: cycleCell: function(idx, column) { }, michael@0: selectionChanged: function() { }, michael@0: performAction: function(action) { }, michael@0: performActionOnCell: function(action, index, column) { }, michael@0: getColumnProperties: function(column) { return ""; }, michael@0: michael@0: get matchCount() this.rowCount, michael@0: michael@0: michael@0: clearResults: function() { michael@0: this.treeData = []; michael@0: }, michael@0: michael@0: addResult: function(result) { michael@0: this.treeData.push(result); michael@0: }, michael@0: michael@0: handleEnter: function(aIsPopupSelection) { michael@0: AutoCompleteE10S.handleEnter(aIsPopupSelection); michael@0: }, michael@0: michael@0: stopSearch: function(){} michael@0: }; michael@0: michael@0: this.AutoCompleteE10S = { michael@0: init: function() { michael@0: let messageManager = Cc["@mozilla.org/globalmessagemanager;1"]. michael@0: getService(Ci.nsIMessageListenerManager); michael@0: messageManager.addMessageListener("FormAutoComplete:SelectBy", this); michael@0: messageManager.addMessageListener("FormAutoComplete:GetSelectedIndex", this); michael@0: messageManager.addMessageListener("FormAutoComplete:ClosePopup", this); michael@0: }, michael@0: michael@0: search: function(message) { michael@0: let browserWindow = message.target.ownerDocument.defaultView; michael@0: this.browser = browserWindow.gBrowser.selectedBrowser; michael@0: this.popup = this.browser.autoCompletePopup; michael@0: this.popup.hidden = false; michael@0: this.popup.setAttribute("width", message.data.width); michael@0: michael@0: let rect = message.data; michael@0: let {x, y} = this.browser.mapScreenCoordinatesFromContent(rect.left, rect.top + rect.height); michael@0: this.x = x; michael@0: this.y = y; michael@0: michael@0: let formAutoComplete = Cc["@mozilla.org/satchel/form-autocomplete;1"] michael@0: .getService(Ci.nsIFormAutoComplete); michael@0: michael@0: formAutoComplete.autoCompleteSearchAsync(message.data.inputName, michael@0: message.data.untrimmedSearchString, michael@0: null, michael@0: null, michael@0: this.onSearchComplete.bind(this)); michael@0: }, michael@0: michael@0: onSearchComplete: function(results) { michael@0: AutoCompleteE10SView.clearResults(); michael@0: michael@0: let resultsArray = []; michael@0: let count = results.matchCount; michael@0: for (let i = 0; i < count; i++) { michael@0: let result = results.getValueAt(i); michael@0: resultsArray.push(result); michael@0: AutoCompleteE10SView.addResult(result); michael@0: } michael@0: michael@0: this.popup.view = AutoCompleteE10SView; michael@0: michael@0: this.browser.messageManager.sendAsyncMessage( michael@0: "FormAutoComplete:AutoCompleteSearchAsyncResult", michael@0: {results: resultsArray} michael@0: ); michael@0: michael@0: this.popup.selectedIndex = -1; michael@0: this.popup.invalidate(); michael@0: michael@0: if (count > 0) { michael@0: this.popup.openPopupAtScreen(this.x, this.y, true); michael@0: // Bug 947503 - This openPopup call is not triggering the "popupshowing" michael@0: // event, which autocomplete.xml uses to track the openness of the popup michael@0: // by setting its mPopupOpen flag. This flag needs to be properly set michael@0: // for closePopup to work. For now, we set it manually. michael@0: this.popup.mPopupOpen = true; michael@0: } else { michael@0: this.popup.closePopup(); michael@0: } michael@0: }, michael@0: michael@0: receiveMessage: function(message) { michael@0: switch (message.name) { michael@0: case "FormAutoComplete:SelectBy": michael@0: this.popup.selectBy(message.data.reverse, message.data.page); michael@0: break; michael@0: michael@0: case "FormAutoComplete:GetSelectedIndex": michael@0: return this.popup.selectedIndex; michael@0: michael@0: case "FormAutoComplete:ClosePopup": michael@0: this.popup.closePopup(); michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: handleEnter: function(aIsPopupSelection) { michael@0: this.browser.messageManager.sendAsyncMessage( michael@0: "FormAutoComplete:HandleEnter", michael@0: { selectedIndex: this.popup.selectedIndex, michael@0: IsPopupSelection: aIsPopupSelection } michael@0: ); michael@0: }, michael@0: michael@0: stopSearch: function() {} michael@0: } michael@0: michael@0: this.AutoCompleteE10S.init();