1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/modules/ContentSearch.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,149 @@ 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 file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +"use strict"; 1.9 + 1.10 +this.EXPORTED_SYMBOLS = [ 1.11 + "ContentSearch", 1.12 +]; 1.13 + 1.14 +const { classes: Cc, interfaces: Ci, utils: Cu } = Components; 1.15 + 1.16 +Cu.import("resource://gre/modules/Services.jsm"); 1.17 + 1.18 +const INBOUND_MESSAGE = "ContentSearch"; 1.19 +const OUTBOUND_MESSAGE = INBOUND_MESSAGE; 1.20 + 1.21 +/** 1.22 + * ContentSearch receives messages named INBOUND_MESSAGE and sends messages 1.23 + * named OUTBOUND_MESSAGE. The data of each message is expected to look like 1.24 + * { type, data }. type is the message's type (or subtype if you consider the 1.25 + * type of the message itself to be INBOUND_MESSAGE), and data is data that is 1.26 + * specific to the type. 1.27 + * 1.28 + * Inbound messages have the following types: 1.29 + * 1.30 + * GetState 1.31 + * Retrieves the current search engine state. 1.32 + * data: null 1.33 + * ManageEngines 1.34 + * Opens the search engine management window. 1.35 + * data: null 1.36 + * Search 1.37 + * Performs a search. 1.38 + * data: an object { engineName, searchString, whence } 1.39 + * SetCurrentEngine 1.40 + * Sets the current engine. 1.41 + * data: the name of the engine 1.42 + * 1.43 + * Outbound messages have the following types: 1.44 + * 1.45 + * CurrentEngine 1.46 + * Sent when the current engine changes. 1.47 + * data: see _currentEngineObj 1.48 + * State 1.49 + * Sent in reply to GetState and when the state changes. 1.50 + * data: see _currentStateObj 1.51 + */ 1.52 + 1.53 +this.ContentSearch = { 1.54 + 1.55 + init: function () { 1.56 + Cc["@mozilla.org/globalmessagemanager;1"]. 1.57 + getService(Ci.nsIMessageListenerManager). 1.58 + addMessageListener(INBOUND_MESSAGE, this); 1.59 + Services.obs.addObserver(this, "browser-search-engine-modified", false); 1.60 + }, 1.61 + 1.62 + receiveMessage: function (msg) { 1.63 + let methodName = "on" + msg.data.type; 1.64 + if (methodName in this) { 1.65 + this[methodName](msg, msg.data.data); 1.66 + } 1.67 + }, 1.68 + 1.69 + onGetState: function (msg, data) { 1.70 + this._reply(msg, "State", this._currentStateObj()); 1.71 + }, 1.72 + 1.73 + onSearch: function (msg, data) { 1.74 + let expectedDataProps = [ 1.75 + "engineName", 1.76 + "searchString", 1.77 + "whence", 1.78 + ]; 1.79 + for (let prop of expectedDataProps) { 1.80 + if (!(prop in data)) { 1.81 + Cu.reportError("Message data missing required property: " + prop); 1.82 + return; 1.83 + } 1.84 + } 1.85 + let browserWin = msg.target.ownerDocument.defaultView; 1.86 + let engine = Services.search.getEngineByName(data.engineName); 1.87 + browserWin.BrowserSearch.recordSearchInHealthReport(engine, data.whence); 1.88 + let submission = engine.getSubmission(data.searchString, "", data.whence); 1.89 + browserWin.loadURI(submission.uri.spec, null, submission.postData); 1.90 + }, 1.91 + 1.92 + onSetCurrentEngine: function (msg, data) { 1.93 + Services.search.currentEngine = Services.search.getEngineByName(data); 1.94 + }, 1.95 + 1.96 + onManageEngines: function (msg, data) { 1.97 + let browserWin = msg.target.ownerDocument.defaultView; 1.98 + browserWin.BrowserSearch.searchBar.openManager(null); 1.99 + }, 1.100 + 1.101 + observe: function (subj, topic, data) { 1.102 + switch (topic) { 1.103 + case "browser-search-engine-modified": 1.104 + if (data == "engine-current") { 1.105 + this._broadcast("CurrentEngine", this._currentEngineObj()); 1.106 + } 1.107 + else if (data != "engine-default") { 1.108 + // engine-default is always sent with engine-current and isn't otherwise 1.109 + // relevant to content searches. 1.110 + this._broadcast("State", this._currentStateObj()); 1.111 + } 1.112 + break; 1.113 + } 1.114 + }, 1.115 + 1.116 + _reply: function (msg, type, data) { 1.117 + msg.target.messageManager.sendAsyncMessage(...this._msgArgs(type, data)); 1.118 + }, 1.119 + 1.120 + _broadcast: function (type, data) { 1.121 + Cc["@mozilla.org/globalmessagemanager;1"]. 1.122 + getService(Ci.nsIMessageListenerManager). 1.123 + broadcastAsyncMessage(...this._msgArgs(type, data)); 1.124 + }, 1.125 + 1.126 + _msgArgs: function (type, data) { 1.127 + return [OUTBOUND_MESSAGE, { 1.128 + type: type, 1.129 + data: data, 1.130 + }]; 1.131 + }, 1.132 + 1.133 + _currentStateObj: function () { 1.134 + return { 1.135 + engines: Services.search.getVisibleEngines().map(engine => { 1.136 + return { 1.137 + name: engine.name, 1.138 + iconURI: engine.getIconURLBySize(16, 16), 1.139 + }; 1.140 + }), 1.141 + currentEngine: this._currentEngineObj(), 1.142 + }; 1.143 + }, 1.144 + 1.145 + _currentEngineObj: function () { 1.146 + return { 1.147 + name: Services.search.currentEngine.name, 1.148 + logoURI: Services.search.currentEngine.getIconURLBySize(65, 26), 1.149 + logo2xURI: Services.search.currentEngine.getIconURLBySize(130, 52), 1.150 + }; 1.151 + }, 1.152 +};