|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 this.EXPORTED_SYMBOLS = [ |
|
8 "ContentSearch", |
|
9 ]; |
|
10 |
|
11 const { classes: Cc, interfaces: Ci, utils: Cu } = Components; |
|
12 |
|
13 Cu.import("resource://gre/modules/Services.jsm"); |
|
14 |
|
15 const INBOUND_MESSAGE = "ContentSearch"; |
|
16 const OUTBOUND_MESSAGE = INBOUND_MESSAGE; |
|
17 |
|
18 /** |
|
19 * ContentSearch receives messages named INBOUND_MESSAGE and sends messages |
|
20 * named OUTBOUND_MESSAGE. The data of each message is expected to look like |
|
21 * { type, data }. type is the message's type (or subtype if you consider the |
|
22 * type of the message itself to be INBOUND_MESSAGE), and data is data that is |
|
23 * specific to the type. |
|
24 * |
|
25 * Inbound messages have the following types: |
|
26 * |
|
27 * GetState |
|
28 * Retrieves the current search engine state. |
|
29 * data: null |
|
30 * ManageEngines |
|
31 * Opens the search engine management window. |
|
32 * data: null |
|
33 * Search |
|
34 * Performs a search. |
|
35 * data: an object { engineName, searchString, whence } |
|
36 * SetCurrentEngine |
|
37 * Sets the current engine. |
|
38 * data: the name of the engine |
|
39 * |
|
40 * Outbound messages have the following types: |
|
41 * |
|
42 * CurrentEngine |
|
43 * Sent when the current engine changes. |
|
44 * data: see _currentEngineObj |
|
45 * State |
|
46 * Sent in reply to GetState and when the state changes. |
|
47 * data: see _currentStateObj |
|
48 */ |
|
49 |
|
50 this.ContentSearch = { |
|
51 |
|
52 init: function () { |
|
53 Cc["@mozilla.org/globalmessagemanager;1"]. |
|
54 getService(Ci.nsIMessageListenerManager). |
|
55 addMessageListener(INBOUND_MESSAGE, this); |
|
56 Services.obs.addObserver(this, "browser-search-engine-modified", false); |
|
57 }, |
|
58 |
|
59 receiveMessage: function (msg) { |
|
60 let methodName = "on" + msg.data.type; |
|
61 if (methodName in this) { |
|
62 this[methodName](msg, msg.data.data); |
|
63 } |
|
64 }, |
|
65 |
|
66 onGetState: function (msg, data) { |
|
67 this._reply(msg, "State", this._currentStateObj()); |
|
68 }, |
|
69 |
|
70 onSearch: function (msg, data) { |
|
71 let expectedDataProps = [ |
|
72 "engineName", |
|
73 "searchString", |
|
74 "whence", |
|
75 ]; |
|
76 for (let prop of expectedDataProps) { |
|
77 if (!(prop in data)) { |
|
78 Cu.reportError("Message data missing required property: " + prop); |
|
79 return; |
|
80 } |
|
81 } |
|
82 let browserWin = msg.target.ownerDocument.defaultView; |
|
83 let engine = Services.search.getEngineByName(data.engineName); |
|
84 browserWin.BrowserSearch.recordSearchInHealthReport(engine, data.whence); |
|
85 let submission = engine.getSubmission(data.searchString, "", data.whence); |
|
86 browserWin.loadURI(submission.uri.spec, null, submission.postData); |
|
87 }, |
|
88 |
|
89 onSetCurrentEngine: function (msg, data) { |
|
90 Services.search.currentEngine = Services.search.getEngineByName(data); |
|
91 }, |
|
92 |
|
93 onManageEngines: function (msg, data) { |
|
94 let browserWin = msg.target.ownerDocument.defaultView; |
|
95 browserWin.BrowserSearch.searchBar.openManager(null); |
|
96 }, |
|
97 |
|
98 observe: function (subj, topic, data) { |
|
99 switch (topic) { |
|
100 case "browser-search-engine-modified": |
|
101 if (data == "engine-current") { |
|
102 this._broadcast("CurrentEngine", this._currentEngineObj()); |
|
103 } |
|
104 else if (data != "engine-default") { |
|
105 // engine-default is always sent with engine-current and isn't otherwise |
|
106 // relevant to content searches. |
|
107 this._broadcast("State", this._currentStateObj()); |
|
108 } |
|
109 break; |
|
110 } |
|
111 }, |
|
112 |
|
113 _reply: function (msg, type, data) { |
|
114 msg.target.messageManager.sendAsyncMessage(...this._msgArgs(type, data)); |
|
115 }, |
|
116 |
|
117 _broadcast: function (type, data) { |
|
118 Cc["@mozilla.org/globalmessagemanager;1"]. |
|
119 getService(Ci.nsIMessageListenerManager). |
|
120 broadcastAsyncMessage(...this._msgArgs(type, data)); |
|
121 }, |
|
122 |
|
123 _msgArgs: function (type, data) { |
|
124 return [OUTBOUND_MESSAGE, { |
|
125 type: type, |
|
126 data: data, |
|
127 }]; |
|
128 }, |
|
129 |
|
130 _currentStateObj: function () { |
|
131 return { |
|
132 engines: Services.search.getVisibleEngines().map(engine => { |
|
133 return { |
|
134 name: engine.name, |
|
135 iconURI: engine.getIconURLBySize(16, 16), |
|
136 }; |
|
137 }), |
|
138 currentEngine: this._currentEngineObj(), |
|
139 }; |
|
140 }, |
|
141 |
|
142 _currentEngineObj: function () { |
|
143 return { |
|
144 name: Services.search.currentEngine.name, |
|
145 logoURI: Services.search.currentEngine.getIconURLBySize(65, 26), |
|
146 logo2xURI: Services.search.currentEngine.getIconURLBySize(130, 52), |
|
147 }; |
|
148 }, |
|
149 }; |