1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/satchel/AutoCompleteE10S.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,159 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +"use strict"; 1.9 + 1.10 +const Cc = Components.classes; 1.11 +const Ci = Components.interfaces; 1.12 +const Cu = Components.utils; 1.13 + 1.14 +this.EXPORTED_SYMBOLS = [ "AutoCompleteE10S" ]; 1.15 + 1.16 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.17 +Cu.import("resource://gre/modules/Services.jsm"); 1.18 + 1.19 +// nsITreeView implementation that feeds the autocomplete popup 1.20 +// with the search data. 1.21 +let AutoCompleteE10SView = { 1.22 + QueryInterface: XPCOMUtils.generateQI([Ci.nsITreeView, 1.23 + Ci.nsIAutoCompleteController]), 1.24 + treeBox: null, 1.25 + selection: null, 1.26 + treeData: [], 1.27 + 1.28 + get rowCount() { return this.treeData.length; }, 1.29 + setTree: function(treeBox) { this.treeBox = treeBox; }, 1.30 + getCellText: function(idx, column) { return this.treeData[idx] }, 1.31 + isContainer: function(idx) { return false; }, 1.32 + getCellValue: function(idx, column){ return false }, 1.33 + isContainerOpen: function(idx) { return false; }, 1.34 + isContainerEmpty: function(idx) { return false; }, 1.35 + isSeparator: function(idx) { return false; }, 1.36 + isSorted: function() { return false; }, 1.37 + isEditable: function(idx, column) { return false; }, 1.38 + canDrop: function(idx, orientation, dt) { return false; }, 1.39 + getLevel: function(idx) { return 0; }, 1.40 + getParentIndex: function(idx) { return -1; }, 1.41 + hasNextSibling: function(idx, after) { return idx < this.treeData.length - 1 }, 1.42 + toggleOpenState: function(idx) { }, 1.43 + getCellProperties: function(idx, column) { return ""; }, 1.44 + getRowProperties: function(idx) { return ""; }, 1.45 + getImageSrc: function(idx, column) { return null; }, 1.46 + getProgressMode : function(idx, column) { }, 1.47 + cycleHeader: function(column) { }, 1.48 + cycleCell: function(idx, column) { }, 1.49 + selectionChanged: function() { }, 1.50 + performAction: function(action) { }, 1.51 + performActionOnCell: function(action, index, column) { }, 1.52 + getColumnProperties: function(column) { return ""; }, 1.53 + 1.54 + get matchCount() this.rowCount, 1.55 + 1.56 + 1.57 + clearResults: function() { 1.58 + this.treeData = []; 1.59 + }, 1.60 + 1.61 + addResult: function(result) { 1.62 + this.treeData.push(result); 1.63 + }, 1.64 + 1.65 + handleEnter: function(aIsPopupSelection) { 1.66 + AutoCompleteE10S.handleEnter(aIsPopupSelection); 1.67 + }, 1.68 + 1.69 + stopSearch: function(){} 1.70 +}; 1.71 + 1.72 +this.AutoCompleteE10S = { 1.73 + init: function() { 1.74 + let messageManager = Cc["@mozilla.org/globalmessagemanager;1"]. 1.75 + getService(Ci.nsIMessageListenerManager); 1.76 + messageManager.addMessageListener("FormAutoComplete:SelectBy", this); 1.77 + messageManager.addMessageListener("FormAutoComplete:GetSelectedIndex", this); 1.78 + messageManager.addMessageListener("FormAutoComplete:ClosePopup", this); 1.79 + }, 1.80 + 1.81 + search: function(message) { 1.82 + let browserWindow = message.target.ownerDocument.defaultView; 1.83 + this.browser = browserWindow.gBrowser.selectedBrowser; 1.84 + this.popup = this.browser.autoCompletePopup; 1.85 + this.popup.hidden = false; 1.86 + this.popup.setAttribute("width", message.data.width); 1.87 + 1.88 + let rect = message.data; 1.89 + let {x, y} = this.browser.mapScreenCoordinatesFromContent(rect.left, rect.top + rect.height); 1.90 + this.x = x; 1.91 + this.y = y; 1.92 + 1.93 + let formAutoComplete = Cc["@mozilla.org/satchel/form-autocomplete;1"] 1.94 + .getService(Ci.nsIFormAutoComplete); 1.95 + 1.96 + formAutoComplete.autoCompleteSearchAsync(message.data.inputName, 1.97 + message.data.untrimmedSearchString, 1.98 + null, 1.99 + null, 1.100 + this.onSearchComplete.bind(this)); 1.101 + }, 1.102 + 1.103 + onSearchComplete: function(results) { 1.104 + AutoCompleteE10SView.clearResults(); 1.105 + 1.106 + let resultsArray = []; 1.107 + let count = results.matchCount; 1.108 + for (let i = 0; i < count; i++) { 1.109 + let result = results.getValueAt(i); 1.110 + resultsArray.push(result); 1.111 + AutoCompleteE10SView.addResult(result); 1.112 + } 1.113 + 1.114 + this.popup.view = AutoCompleteE10SView; 1.115 + 1.116 + this.browser.messageManager.sendAsyncMessage( 1.117 + "FormAutoComplete:AutoCompleteSearchAsyncResult", 1.118 + {results: resultsArray} 1.119 + ); 1.120 + 1.121 + this.popup.selectedIndex = -1; 1.122 + this.popup.invalidate(); 1.123 + 1.124 + if (count > 0) { 1.125 + this.popup.openPopupAtScreen(this.x, this.y, true); 1.126 + // Bug 947503 - This openPopup call is not triggering the "popupshowing" 1.127 + // event, which autocomplete.xml uses to track the openness of the popup 1.128 + // by setting its mPopupOpen flag. This flag needs to be properly set 1.129 + // for closePopup to work. For now, we set it manually. 1.130 + this.popup.mPopupOpen = true; 1.131 + } else { 1.132 + this.popup.closePopup(); 1.133 + } 1.134 + }, 1.135 + 1.136 + receiveMessage: function(message) { 1.137 + switch (message.name) { 1.138 + case "FormAutoComplete:SelectBy": 1.139 + this.popup.selectBy(message.data.reverse, message.data.page); 1.140 + break; 1.141 + 1.142 + case "FormAutoComplete:GetSelectedIndex": 1.143 + return this.popup.selectedIndex; 1.144 + 1.145 + case "FormAutoComplete:ClosePopup": 1.146 + this.popup.closePopup(); 1.147 + break; 1.148 + } 1.149 + }, 1.150 + 1.151 + handleEnter: function(aIsPopupSelection) { 1.152 + this.browser.messageManager.sendAsyncMessage( 1.153 + "FormAutoComplete:HandleEnter", 1.154 + { selectedIndex: this.popup.selectedIndex, 1.155 + IsPopupSelection: aIsPopupSelection } 1.156 + ); 1.157 + }, 1.158 + 1.159 + stopSearch: function() {} 1.160 +} 1.161 + 1.162 +this.AutoCompleteE10S.init();