OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 12 matching lines...) Expand all Loading... |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 /* eslint-disable indent */ | 31 /* eslint-disable indent */ |
32 | 32 |
33 function defineCommonExtensionSymbols(apiPrivate) | 33 function defineCommonExtensionSymbols(apiPrivate) { |
34 { | 34 if (!apiPrivate.audits) |
35 if (!apiPrivate.audits) | 35 apiPrivate.audits = {}; |
36 apiPrivate.audits = {}; | 36 apiPrivate.audits.Severity = {Info: 'info', Warning: 'warning', Severe: 'sever
e'}; |
37 apiPrivate.audits.Severity = { | |
38 Info: "info", | |
39 Warning: "warning", | |
40 Severe: "severe" | |
41 }; | |
42 | 37 |
43 if (!apiPrivate.panels) | 38 if (!apiPrivate.panels) |
44 apiPrivate.panels = {}; | 39 apiPrivate.panels = {}; |
45 apiPrivate.panels.SearchAction = { | 40 apiPrivate.panels.SearchAction = { |
46 CancelSearch: "cancelSearch", | 41 CancelSearch: 'cancelSearch', |
47 PerformSearch: "performSearch", | 42 PerformSearch: 'performSearch', |
48 NextSearchResult: "nextSearchResult", | 43 NextSearchResult: 'nextSearchResult', |
49 PreviousSearchResult: "previousSearchResult" | 44 PreviousSearchResult: 'previousSearchResult' |
50 }; | 45 }; |
51 | 46 |
52 /** @enum {string} */ | 47 /** @enum {string} */ |
53 apiPrivate.Events = { | 48 apiPrivate.Events = { |
54 AuditStarted: "audit-started-", | 49 AuditStarted: 'audit-started-', |
55 ButtonClicked: "button-clicked-", | 50 ButtonClicked: 'button-clicked-', |
56 PanelObjectSelected: "panel-objectSelected-", | 51 PanelObjectSelected: 'panel-objectSelected-', |
57 NetworkRequestFinished: "network-request-finished", | 52 NetworkRequestFinished: 'network-request-finished', |
58 OpenResource: "open-resource", | 53 OpenResource: 'open-resource', |
59 PanelSearch: "panel-search-", | 54 PanelSearch: 'panel-search-', |
60 RecordingStarted: "trace-recording-started-", | 55 RecordingStarted: 'trace-recording-started-', |
61 RecordingStopped: "trace-recording-stopped-", | 56 RecordingStopped: 'trace-recording-stopped-', |
62 ResourceAdded: "resource-added", | 57 ResourceAdded: 'resource-added', |
63 ResourceContentCommitted: "resource-content-committed", | 58 ResourceContentCommitted: 'resource-content-committed', |
64 ViewShown: "view-shown-", | 59 ViewShown: 'view-shown-', |
65 ViewHidden: "view-hidden-" | 60 ViewHidden: 'view-hidden-' |
66 }; | 61 }; |
67 | 62 |
68 /** @enum {string} */ | 63 /** @enum {string} */ |
69 apiPrivate.Commands = { | 64 apiPrivate.Commands = { |
70 AddAuditCategory: "addAuditCategory", | 65 AddAuditCategory: 'addAuditCategory', |
71 AddAuditResult: "addAuditResult", | 66 AddAuditResult: 'addAuditResult', |
72 AddRequestHeaders: "addRequestHeaders", | 67 AddRequestHeaders: 'addRequestHeaders', |
73 AddTraceProvider: "addTraceProvider", | 68 AddTraceProvider: 'addTraceProvider', |
74 ApplyStyleSheet: "applyStyleSheet", | 69 ApplyStyleSheet: 'applyStyleSheet', |
75 CreatePanel: "createPanel", | 70 CreatePanel: 'createPanel', |
76 CreateSidebarPane: "createSidebarPane", | 71 CreateSidebarPane: 'createSidebarPane', |
77 CreateToolbarButton: "createToolbarButton", | 72 CreateToolbarButton: 'createToolbarButton', |
78 EvaluateOnInspectedPage: "evaluateOnInspectedPage", | 73 EvaluateOnInspectedPage: 'evaluateOnInspectedPage', |
79 ForwardKeyboardEvent: "_forwardKeyboardEvent", | 74 ForwardKeyboardEvent: '_forwardKeyboardEvent', |
80 GetHAR: "getHAR", | 75 GetHAR: 'getHAR', |
81 GetPageResources: "getPageResources", | 76 GetPageResources: 'getPageResources', |
82 GetRequestContent: "getRequestContent", | 77 GetRequestContent: 'getRequestContent', |
83 GetResourceContent: "getResourceContent", | 78 GetResourceContent: 'getResourceContent', |
84 InspectedURLChanged: "inspectedURLChanged", | 79 InspectedURLChanged: 'inspectedURLChanged', |
85 OpenResource: "openResource", | 80 OpenResource: 'openResource', |
86 Reload: "Reload", | 81 Reload: 'Reload', |
87 Subscribe: "subscribe", | 82 Subscribe: 'subscribe', |
88 SetOpenResourceHandler: "setOpenResourceHandler", | 83 SetOpenResourceHandler: 'setOpenResourceHandler', |
89 SetResourceContent: "setResourceContent", | 84 SetResourceContent: 'setResourceContent', |
90 SetSidebarContent: "setSidebarContent", | 85 SetSidebarContent: 'setSidebarContent', |
91 SetSidebarHeight: "setSidebarHeight", | 86 SetSidebarHeight: 'setSidebarHeight', |
92 SetSidebarPage: "setSidebarPage", | 87 SetSidebarPage: 'setSidebarPage', |
93 ShowPanel: "showPanel", | 88 ShowPanel: 'showPanel', |
94 StopAuditCategoryRun: "stopAuditCategoryRun", | 89 StopAuditCategoryRun: 'stopAuditCategoryRun', |
95 Unsubscribe: "unsubscribe", | 90 Unsubscribe: 'unsubscribe', |
96 UpdateAuditProgress: "updateAuditProgress", | 91 UpdateAuditProgress: 'updateAuditProgress', |
97 UpdateButton: "updateButton" | 92 UpdateButton: 'updateButton' |
98 }; | 93 }; |
99 } | 94 } |
100 | 95 |
101 /** | 96 /** |
102 * @param {!ExtensionDescriptor} extensionInfo | 97 * @param {!ExtensionDescriptor} extensionInfo |
103 * @param {string} inspectedTabId | 98 * @param {string} inspectedTabId |
104 * @param {string} themeName | 99 * @param {string} themeName |
105 * @param {number} injectedScriptId | 100 * @param {number} injectedScriptId |
106 * @param {function(!Object, !Object)} testHook | 101 * @param {function(!Object, !Object)} testHook |
107 * @suppressGlobalPropertiesCheck | 102 * @suppressGlobalPropertiesCheck |
108 */ | 103 */ |
109 function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook
, injectedScriptId) | 104 function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook
, injectedScriptId) { |
110 { | 105 var apiPrivate = {}; |
111 | 106 |
112 var apiPrivate = {}; | 107 defineCommonExtensionSymbols(apiPrivate); |
113 | 108 |
114 defineCommonExtensionSymbols(apiPrivate); | 109 var commands = apiPrivate.Commands; |
115 | 110 var events = apiPrivate.Events; |
116 var commands = apiPrivate.Commands; | 111 var userAction = false; |
117 var events = apiPrivate.Events; | 112 |
118 var userAction = false; | 113 // Here and below, all constructors are private to API implementation. |
119 | 114 // For a public type Foo, if internal fields are present, these are on |
120 // Here and below, all constructors are private to API implementation. | 115 // a private FooImpl type, an instance of FooImpl is used in a closure |
121 // For a public type Foo, if internal fields are present, these are on | 116 // by Foo consutrctor to re-bind publicly exported members to an instance |
122 // a private FooImpl type, an instance of FooImpl is used in a closure | 117 // of Foo. |
123 // by Foo consutrctor to re-bind publicly exported members to an instance | 118 |
124 // of Foo. | 119 /** |
125 | 120 * @constructor |
126 /** | 121 */ |
127 * @constructor | 122 function EventSinkImpl(type, customDispatch) { |
128 */ | |
129 function EventSinkImpl(type, customDispatch) | |
130 { | |
131 this._type = type; | 123 this._type = type; |
132 this._listeners = []; | 124 this._listeners = []; |
133 this._customDispatch = customDispatch; | 125 this._customDispatch = customDispatch; |
134 } | 126 } |
135 | 127 |
136 EventSinkImpl.prototype = { | 128 EventSinkImpl.prototype = { |
137 addListener: function(callback) | 129 addListener: function(callback) { |
138 { | 130 if (typeof callback !== 'function') |
139 if (typeof callback !== "function") | 131 throw 'addListener: callback is not a function'; |
140 throw "addListener: callback is not a function"; | 132 if (this._listeners.length === 0) |
141 if (this._listeners.length === 0) | 133 extensionServer.sendRequest({command: commands.Subscribe, type: this._ty
pe}); |
142 extensionServer.sendRequest({ command: commands.Subscribe, type: thi
s._type }); | 134 this._listeners.push(callback); |
143 this._listeners.push(callback); | 135 extensionServer.registerHandler('notify-' + this._type, this._dispatch.bin
d(this)); |
144 extensionServer.registerHandler("notify-" + this._type, this._dispatch.b
ind(this)); | 136 }, |
145 }, | 137 |
146 | 138 removeListener: function(callback) { |
147 removeListener: function(callback) | 139 var listeners = this._listeners; |
148 { | 140 |
149 var listeners = this._listeners; | 141 for (var i = 0; i < listeners.length; ++i) { |
150 | 142 if (listeners[i] === callback) { |
151 for (var i = 0; i < listeners.length; ++i) { | 143 listeners.splice(i, 1); |
152 if (listeners[i] === callback) { | 144 break; |
153 listeners.splice(i, 1); | |
154 break; | |
155 } | |
156 } | 145 } |
157 if (this._listeners.length === 0) | 146 } |
158 extensionServer.sendRequest({ command: commands.Unsubscribe, type: t
his._type }); | 147 if (this._listeners.length === 0) |
| 148 extensionServer.sendRequest({command: commands.Unsubscribe, type: this._
type}); |
159 }, | 149 }, |
160 | 150 |
161 /** | 151 /** |
162 * @param {...} vararg | 152 * @param {...} vararg |
163 */ | 153 */ |
164 _fire: function(vararg) | 154 _fire: function(vararg) { |
165 { | 155 var listeners = this._listeners.slice(); |
166 var listeners = this._listeners.slice(); | 156 for (var i = 0; i < listeners.length; ++i) |
167 for (var i = 0; i < listeners.length; ++i) | 157 listeners[i].apply(null, arguments); |
168 listeners[i].apply(null, arguments); | 158 }, |
169 }, | 159 |
170 | 160 _dispatch: function(request) { |
171 _dispatch: function(request) | 161 if (this._customDispatch) |
172 { | 162 this._customDispatch.call(this, request); |
173 if (this._customDispatch) | 163 else |
174 this._customDispatch.call(this, request); | 164 this._fire.apply(this, request.arguments); |
175 else | 165 } |
176 this._fire.apply(this, request.arguments); | 166 }; |
177 } | 167 |
178 }; | 168 /** |
179 | 169 * @constructor |
180 /** | 170 */ |
181 * @constructor | 171 function InspectorExtensionAPI() { |
182 */ | |
183 function InspectorExtensionAPI() | |
184 { | |
185 this.audits = new Audits(); | 172 this.audits = new Audits(); |
186 this.inspectedWindow = new InspectedWindow(); | 173 this.inspectedWindow = new InspectedWindow(); |
187 this.panels = new Panels(); | 174 this.panels = new Panels(); |
188 this.network = new Network(); | 175 this.network = new Network(); |
189 this.timeline = new Timeline(); | 176 this.timeline = new Timeline(); |
190 defineDeprecatedProperty(this, "webInspector", "resources", "network"); | 177 defineDeprecatedProperty(this, 'webInspector', 'resources', 'network'); |
191 } | 178 } |
192 | 179 |
193 /** | 180 /** |
194 * @constructor | 181 * @constructor |
195 */ | 182 */ |
196 function Network() | 183 function Network() { |
197 { | |
198 /** | 184 /** |
199 * @this {EventSinkImpl} | 185 * @this {EventSinkImpl} |
200 */ | 186 */ |
201 function dispatchRequestEvent(message) | 187 function dispatchRequestEvent(message) { |
202 { | 188 var request = message.arguments[1]; |
203 var request = message.arguments[1]; | 189 request.__proto__ = new Request(message.arguments[0]); |
204 request.__proto__ = new Request(message.arguments[0]); | 190 this._fire(request); |
205 this._fire(request); | |
206 } | 191 } |
207 this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispat
chRequestEvent); | 192 this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispat
chRequestEvent); |
208 defineDeprecatedProperty(this, "network", "onFinished", "onRequestFinished")
; | 193 defineDeprecatedProperty(this, 'network', 'onFinished', 'onRequestFinished')
; |
209 this.onNavigated = new EventSink(events.InspectedURLChanged); | 194 this.onNavigated = new EventSink(events.InspectedURLChanged); |
210 } | 195 } |
211 | 196 |
212 Network.prototype = { | 197 Network.prototype = { |
213 getHAR: function(callback) | 198 getHAR: function(callback) { |
214 { | 199 function callbackWrapper(result) { |
215 function callbackWrapper(result) | 200 var entries = (result && result.entries) || []; |
216 { | 201 for (var i = 0; i < entries.length; ++i) { |
217 var entries = (result && result.entries) || []; | 202 entries[i].__proto__ = new Request(entries[i]._requestId); |
218 for (var i = 0; i < entries.length; ++i) { | 203 delete entries[i]._requestId; |
219 entries[i].__proto__ = new Request(entries[i]._requestId); | |
220 delete entries[i]._requestId; | |
221 } | |
222 callback(result); | |
223 } | 204 } |
224 extensionServer.sendRequest({ command: commands.GetHAR }, callback && ca
llbackWrapper); | 205 callback(result); |
225 }, | 206 } |
226 | 207 extensionServer.sendRequest({command: commands.GetHAR}, callback && callba
ckWrapper); |
227 addRequestHeaders: function(headers) | 208 }, |
228 { | 209 |
229 extensionServer.sendRequest({ command: commands.AddRequestHeaders, heade
rs: headers, extensionId: window.location.hostname }); | 210 addRequestHeaders: function(headers) { |
230 } | 211 extensionServer.sendRequest( |
231 }; | 212 {command: commands.AddRequestHeaders, headers: headers, extensionId: w
indow.location.hostname}); |
232 | 213 } |
233 /** | 214 }; |
234 * @constructor | 215 |
235 */ | 216 /** |
236 function RequestImpl(id) | 217 * @constructor |
237 { | 218 */ |
| 219 function RequestImpl(id) { |
238 this._id = id; | 220 this._id = id; |
239 } | 221 } |
240 | 222 |
241 RequestImpl.prototype = { | 223 RequestImpl.prototype = { |
242 getContent: function(callback) | 224 getContent: function(callback) { |
243 { | 225 function callbackWrapper(response) { |
244 function callbackWrapper(response) | 226 callback(response.content, response.encoding); |
245 { | 227 } |
246 callback(response.content, response.encoding); | 228 extensionServer.sendRequest({command: commands.GetRequestContent, id: this
._id}, callback && callbackWrapper); |
| 229 } |
| 230 }; |
| 231 |
| 232 /** |
| 233 * @constructor |
| 234 */ |
| 235 function Panels() { |
| 236 var panels = { |
| 237 elements: new ElementsPanel(), |
| 238 sources: new SourcesPanel(), |
| 239 }; |
| 240 |
| 241 function panelGetter(name) { |
| 242 return panels[name]; |
| 243 } |
| 244 for (var panel in panels) |
| 245 this.__defineGetter__(panel, panelGetter.bind(null, panel)); |
| 246 this.applyStyleSheet = function(styleSheet) { |
| 247 extensionServer.sendRequest({command: commands.ApplyStyleSheet, styleSheet
: styleSheet}); |
| 248 }; |
| 249 } |
| 250 |
| 251 Panels.prototype = { |
| 252 create: function(title, icon, page, callback) { |
| 253 var id = 'extension-panel-' + extensionServer.nextObjectId(); |
| 254 var request = {command: commands.CreatePanel, id: id, title: title, icon:
icon, page: page}; |
| 255 extensionServer.sendRequest(request, callback && callback.bind(this, new E
xtensionPanel(id))); |
| 256 }, |
| 257 |
| 258 setOpenResourceHandler: function(callback) { |
| 259 var hadHandler = extensionServer.hasHandler(events.OpenResource); |
| 260 |
| 261 function callbackWrapper(message) { |
| 262 // Allow the panel to show itself when handling the event. |
| 263 userAction = true; |
| 264 try { |
| 265 callback.call(null, new Resource(message.resource), message.lineNumber
); |
| 266 } finally { |
| 267 userAction = false; |
247 } | 268 } |
248 extensionServer.sendRequest({ command: commands.GetRequestContent, id: t
his._id }, callback && callbackWrapper); | 269 } |
249 } | 270 |
250 }; | 271 if (!callback) |
251 | 272 extensionServer.unregisterHandler(events.OpenResource); |
252 /** | 273 else |
253 * @constructor | 274 extensionServer.registerHandler(events.OpenResource, callbackWrapper); |
254 */ | 275 |
255 function Panels() | 276 // Only send command if we either removed an existing handler or added han
dler and had none before. |
256 { | 277 if (hadHandler === !callback) |
257 var panels = { | 278 extensionServer.sendRequest({command: commands.SetOpenResourceHandler, '
handlerPresent': !!callback}); |
258 elements: new ElementsPanel(), | 279 }, |
259 sources: new SourcesPanel(), | 280 |
260 }; | 281 openResource: function(url, lineNumber, callback) { |
261 | 282 extensionServer.sendRequest({command: commands.OpenResource, 'url': url, '
lineNumber': lineNumber}, callback); |
262 function panelGetter(name) | 283 }, |
263 { | 284 |
264 return panels[name]; | 285 get SearchAction() { |
265 } | 286 return apiPrivate.panels.SearchAction; |
266 for (var panel in panels) | 287 } |
267 this.__defineGetter__(panel, panelGetter.bind(null, panel)); | 288 }; |
268 this.applyStyleSheet = function(styleSheet) { extensionServer.sendRequest({
command: commands.ApplyStyleSheet, styleSheet: styleSheet }); }; | 289 |
269 } | 290 /** |
270 | 291 * @constructor |
271 Panels.prototype = { | 292 */ |
272 create: function(title, icon, page, callback) | 293 function ExtensionViewImpl(id) { |
273 { | |
274 var id = "extension-panel-" + extensionServer.nextObjectId(); | |
275 var request = { | |
276 command: commands.CreatePanel, | |
277 id: id, | |
278 title: title, | |
279 icon: icon, | |
280 page: page | |
281 }; | |
282 extensionServer.sendRequest(request, callback && callback.bind(this, new
ExtensionPanel(id))); | |
283 }, | |
284 | |
285 setOpenResourceHandler: function(callback) | |
286 { | |
287 var hadHandler = extensionServer.hasHandler(events.OpenResource); | |
288 | |
289 function callbackWrapper(message) | |
290 { | |
291 // Allow the panel to show itself when handling the event. | |
292 userAction = true; | |
293 try { | |
294 callback.call(null, new Resource(message.resource), message.line
Number); | |
295 } finally { | |
296 userAction = false; | |
297 } | |
298 } | |
299 | |
300 if (!callback) | |
301 extensionServer.unregisterHandler(events.OpenResource); | |
302 else | |
303 extensionServer.registerHandler(events.OpenResource, callbackWrapper
); | |
304 | |
305 // Only send command if we either removed an existing handler or added h
andler and had none before. | |
306 if (hadHandler === !callback) | |
307 extensionServer.sendRequest({ command: commands.SetOpenResourceHandl
er, "handlerPresent": !!callback }); | |
308 }, | |
309 | |
310 openResource: function(url, lineNumber, callback) | |
311 { | |
312 extensionServer.sendRequest({ command: commands.OpenResource, "url": url
, "lineNumber": lineNumber }, callback); | |
313 }, | |
314 | |
315 get SearchAction() | |
316 { | |
317 return apiPrivate.panels.SearchAction; | |
318 } | |
319 }; | |
320 | |
321 /** | |
322 * @constructor | |
323 */ | |
324 function ExtensionViewImpl(id) | |
325 { | |
326 this._id = id; | 294 this._id = id; |
327 | 295 |
328 /** | 296 /** |
329 * @this {EventSinkImpl} | 297 * @this {EventSinkImpl} |
330 */ | 298 */ |
331 function dispatchShowEvent(message) | 299 function dispatchShowEvent(message) { |
332 { | 300 var frameIndex = message.arguments[0]; |
333 var frameIndex = message.arguments[0]; | 301 if (typeof frameIndex === 'number') |
334 if (typeof frameIndex === "number") | 302 this._fire(window.parent.frames[frameIndex]); |
335 this._fire(window.parent.frames[frameIndex]); | 303 else |
336 else | 304 this._fire(); |
337 this._fire(); | |
338 } | 305 } |
339 | 306 |
340 if (id) { | 307 if (id) { |
341 this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent); | 308 this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent); |
342 this.onHidden = new EventSink(events.ViewHidden + id); | 309 this.onHidden = new EventSink(events.ViewHidden + id); |
343 } | 310 } |
344 } | 311 } |
345 | 312 |
346 /** | 313 /** |
347 * @constructor | 314 * @constructor |
348 * @extends {ExtensionViewImpl} | 315 * @extends {ExtensionViewImpl} |
349 * @param {string} hostPanelName | 316 * @param {string} hostPanelName |
350 */ | 317 */ |
351 function PanelWithSidebarImpl(hostPanelName) | 318 function PanelWithSidebarImpl(hostPanelName) { |
352 { | |
353 ExtensionViewImpl.call(this, null); | 319 ExtensionViewImpl.call(this, null); |
354 this._hostPanelName = hostPanelName; | 320 this._hostPanelName = hostPanelName; |
355 this.onSelectionChanged = new EventSink(events.PanelObjectSelected + hostPan
elName); | 321 this.onSelectionChanged = new EventSink(events.PanelObjectSelected + hostPan
elName); |
356 } | 322 } |
357 | 323 |
358 PanelWithSidebarImpl.prototype = { | 324 PanelWithSidebarImpl.prototype = { |
359 createSidebarPane: function(title, callback) | 325 createSidebarPane: function(title, callback) { |
360 { | 326 var id = 'extension-sidebar-' + extensionServer.nextObjectId(); |
361 var id = "extension-sidebar-" + extensionServer.nextObjectId(); | 327 var request = {command: commands.CreateSidebarPane, panel: this._hostPanel
Name, id: id, title: title}; |
362 var request = { | 328 function callbackWrapper() { |
363 command: commands.CreateSidebarPane, | 329 callback(new ExtensionSidebarPane(id)); |
364 panel: this._hostPanelName, | 330 } |
365 id: id, | 331 extensionServer.sendRequest(request, callback && callbackWrapper); |
366 title: title | |
367 }; | |
368 function callbackWrapper() | |
369 { | |
370 callback(new ExtensionSidebarPane(id)); | |
371 } | |
372 extensionServer.sendRequest(request, callback && callbackWrapper); | |
373 }, | 332 }, |
374 | 333 |
375 __proto__: ExtensionViewImpl.prototype | 334 __proto__: ExtensionViewImpl.prototype |
376 }; | 335 }; |
377 | 336 |
378 function declareInterfaceClass(implConstructor) | 337 function declareInterfaceClass(implConstructor) { |
379 { | 338 return function() { |
380 return function() | 339 var impl = {__proto__: implConstructor.prototype}; |
381 { | 340 implConstructor.apply(impl, arguments); |
382 var impl = { __proto__: implConstructor.prototype }; | 341 populateInterfaceClass(this, impl); |
383 implConstructor.apply(impl, arguments); | |
384 populateInterfaceClass(this, impl); | |
385 }; | 342 }; |
386 } | 343 } |
387 | 344 |
388 function defineDeprecatedProperty(object, className, oldName, newName) | 345 function defineDeprecatedProperty(object, className, oldName, newName) { |
389 { | |
390 var warningGiven = false; | 346 var warningGiven = false; |
391 function getter() | 347 function getter() { |
392 { | 348 if (!warningGiven) { |
393 if (!warningGiven) { | 349 console.warn(className + '.' + oldName + ' is deprecated. Use ' + classN
ame + '.' + newName + ' instead'); |
394 console.warn(className + "." + oldName + " is deprecated. Use " + cl
assName + "." + newName + " instead"); | 350 warningGiven = true; |
395 warningGiven = true; | 351 } |
396 } | 352 return object[newName]; |
397 return object[newName]; | |
398 } | 353 } |
399 object.__defineGetter__(oldName, getter); | 354 object.__defineGetter__(oldName, getter); |
400 } | 355 } |
401 | 356 |
402 function extractCallbackArgument(args) | 357 function extractCallbackArgument(args) { |
403 { | |
404 var lastArgument = args[args.length - 1]; | 358 var lastArgument = args[args.length - 1]; |
405 return typeof lastArgument === "function" ? lastArgument : undefined; | 359 return typeof lastArgument === 'function' ? lastArgument : undefined; |
406 } | 360 } |
407 | 361 |
408 var AuditCategory = declareInterfaceClass(AuditCategoryImpl); | 362 var AuditCategory = declareInterfaceClass(AuditCategoryImpl); |
409 var AuditResult = declareInterfaceClass(AuditResultImpl); | 363 var AuditResult = declareInterfaceClass(AuditResultImpl); |
410 var Button = declareInterfaceClass(ButtonImpl); | 364 var Button = declareInterfaceClass(ButtonImpl); |
411 var EventSink = declareInterfaceClass(EventSinkImpl); | 365 var EventSink = declareInterfaceClass(EventSinkImpl); |
412 var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl); | 366 var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl); |
413 var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl); | 367 var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl); |
414 var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl); | 368 var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl); |
415 var Request = declareInterfaceClass(RequestImpl); | 369 var Request = declareInterfaceClass(RequestImpl); |
416 var Resource = declareInterfaceClass(ResourceImpl); | 370 var Resource = declareInterfaceClass(ResourceImpl); |
417 | 371 |
418 /** | 372 /** |
419 * @constructor | 373 * @constructor |
420 * @extends {PanelWithSidebar} | 374 * @extends {PanelWithSidebar} |
421 */ | 375 */ |
422 function ElementsPanel() | 376 function ElementsPanel() { |
423 { | 377 PanelWithSidebar.call(this, 'elements'); |
424 PanelWithSidebar.call(this, "elements"); | 378 } |
425 } | 379 |
426 | 380 ElementsPanel.prototype = {__proto__: PanelWithSidebar.prototype}; |
427 ElementsPanel.prototype = { | 381 |
428 __proto__: PanelWithSidebar.prototype | 382 /** |
429 }; | 383 * @constructor |
430 | 384 * @extends {PanelWithSidebar} |
431 /** | 385 */ |
432 * @constructor | 386 function SourcesPanel() { |
433 * @extends {PanelWithSidebar} | 387 PanelWithSidebar.call(this, 'sources'); |
434 */ | 388 } |
435 function SourcesPanel() | 389 |
436 { | 390 SourcesPanel.prototype = {__proto__: PanelWithSidebar.prototype}; |
437 PanelWithSidebar.call(this, "sources"); | 391 |
438 } | 392 /** |
439 | 393 * @constructor |
440 SourcesPanel.prototype = { | 394 * @extends {ExtensionViewImpl} |
441 __proto__: PanelWithSidebar.prototype | 395 */ |
442 }; | 396 function ExtensionPanelImpl(id) { |
443 | |
444 /** | |
445 * @constructor | |
446 * @extends {ExtensionViewImpl} | |
447 */ | |
448 function ExtensionPanelImpl(id) | |
449 { | |
450 ExtensionViewImpl.call(this, id); | 397 ExtensionViewImpl.call(this, id); |
451 this.onSearch = new EventSink(events.PanelSearch + id); | 398 this.onSearch = new EventSink(events.PanelSearch + id); |
452 } | 399 } |
453 | 400 |
454 ExtensionPanelImpl.prototype = { | 401 ExtensionPanelImpl.prototype = { |
455 /** | 402 /** |
456 * @return {!Object} | 403 * @return {!Object} |
457 */ | 404 */ |
458 createStatusBarButton: function(iconPath, tooltipText, disabled) | 405 createStatusBarButton: function(iconPath, tooltipText, disabled) { |
459 { | 406 var id = 'button-' + extensionServer.nextObjectId(); |
460 var id = "button-" + extensionServer.nextObjectId(); | 407 var request = { |
461 var request = { | 408 command: commands.CreateToolbarButton, |
462 command: commands.CreateToolbarButton, | 409 panel: this._id, |
463 panel: this._id, | 410 id: id, |
464 id: id, | 411 icon: iconPath, |
465 icon: iconPath, | 412 tooltip: tooltipText, |
466 tooltip: tooltipText, | 413 disabled: !!disabled |
467 disabled: !!disabled | 414 }; |
468 }; | 415 extensionServer.sendRequest(request); |
469 extensionServer.sendRequest(request); | 416 return new Button(id); |
470 return new Button(id); | 417 }, |
471 }, | 418 |
472 | 419 show: function() { |
473 show: function() | 420 if (!userAction) |
474 { | 421 return; |
475 if (!userAction) | 422 |
476 return; | 423 var request = {command: commands.ShowPanel, id: this._id}; |
477 | 424 extensionServer.sendRequest(request); |
478 var request = { | |
479 command: commands.ShowPanel, | |
480 id: this._id | |
481 }; | |
482 extensionServer.sendRequest(request); | |
483 }, | 425 }, |
484 | 426 |
485 __proto__: ExtensionViewImpl.prototype | 427 __proto__: ExtensionViewImpl.prototype |
486 }; | 428 }; |
487 | 429 |
488 /** | 430 /** |
489 * @constructor | 431 * @constructor |
490 * @extends {ExtensionViewImpl} | 432 * @extends {ExtensionViewImpl} |
491 */ | 433 */ |
492 function ExtensionSidebarPaneImpl(id) | 434 function ExtensionSidebarPaneImpl(id) { |
493 { | |
494 ExtensionViewImpl.call(this, id); | 435 ExtensionViewImpl.call(this, id); |
495 } | 436 } |
496 | 437 |
497 ExtensionSidebarPaneImpl.prototype = { | 438 ExtensionSidebarPaneImpl.prototype = { |
498 setHeight: function(height) | 439 setHeight: function(height) { |
499 { | 440 extensionServer.sendRequest({command: commands.SetSidebarHeight, id: this.
_id, height: height}); |
500 extensionServer.sendRequest({ command: commands.SetSidebarHeight, id: th
is._id, height: height }); | 441 }, |
501 }, | 442 |
502 | 443 setExpression: function(expression, rootTitle, evaluateOptions) { |
503 setExpression: function(expression, rootTitle, evaluateOptions) | 444 var request = { |
504 { | 445 command: commands.SetSidebarContent, |
505 var request = { | 446 id: this._id, |
506 command: commands.SetSidebarContent, | 447 expression: expression, |
507 id: this._id, | 448 rootTitle: rootTitle, |
508 expression: expression, | 449 evaluateOnPage: true, |
509 rootTitle: rootTitle, | 450 }; |
510 evaluateOnPage: true, | 451 if (typeof evaluateOptions === 'object') |
511 }; | 452 request.evaluateOptions = evaluateOptions; |
512 if (typeof evaluateOptions === "object") | 453 extensionServer.sendRequest(request, extractCallbackArgument(arguments)); |
513 request.evaluateOptions = evaluateOptions; | 454 }, |
514 extensionServer.sendRequest(request, extractCallbackArgument(arguments))
; | 455 |
515 }, | 456 setObject: function(jsonObject, rootTitle, callback) { |
516 | 457 extensionServer.sendRequest( |
517 setObject: function(jsonObject, rootTitle, callback) | 458 {command: commands.SetSidebarContent, id: this._id, expression: jsonOb
ject, rootTitle: rootTitle}, callback); |
518 { | 459 }, |
519 extensionServer.sendRequest({ command: commands.SetSidebarContent, id: t
his._id, expression: jsonObject, rootTitle: rootTitle }, callback); | 460 |
520 }, | 461 setPage: function(page) { |
521 | 462 extensionServer.sendRequest({command: commands.SetSidebarPage, id: this._i
d, page: page}); |
522 setPage: function(page) | |
523 { | |
524 extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this
._id, page: page }); | |
525 }, | 463 }, |
526 | 464 |
527 __proto__: ExtensionViewImpl.prototype | 465 __proto__: ExtensionViewImpl.prototype |
528 }; | 466 }; |
529 | 467 |
530 /** | 468 /** |
531 * @constructor | 469 * @constructor |
532 */ | 470 */ |
533 function ButtonImpl(id) | 471 function ButtonImpl(id) { |
534 { | |
535 this._id = id; | 472 this._id = id; |
536 this.onClicked = new EventSink(events.ButtonClicked + id); | 473 this.onClicked = new EventSink(events.ButtonClicked + id); |
537 } | 474 } |
538 | 475 |
539 ButtonImpl.prototype = { | 476 ButtonImpl.prototype = { |
540 update: function(iconPath, tooltipText, disabled) | 477 update: function(iconPath, tooltipText, disabled) { |
541 { | 478 var request = |
542 var request = { | 479 {command: commands.UpdateButton, id: this._id, icon: iconPath, tooltip
: tooltipText, disabled: !!disabled}; |
543 command: commands.UpdateButton, | 480 extensionServer.sendRequest(request); |
544 id: this._id, | 481 } |
545 icon: iconPath, | 482 }; |
546 tooltip: tooltipText, | 483 |
547 disabled: !!disabled | 484 /** |
548 }; | 485 * @constructor |
549 extensionServer.sendRequest(request); | 486 */ |
550 } | 487 function Timeline() { |
551 }; | 488 } |
552 | 489 |
553 /** | 490 Timeline.prototype = { |
554 * @constructor | |
555 */ | |
556 function Timeline() | |
557 { | |
558 } | |
559 | |
560 Timeline.prototype = { | |
561 /** | 491 /** |
562 * @param {string} categoryName | 492 * @param {string} categoryName |
563 * @param {string} categoryTooltip | 493 * @param {string} categoryTooltip |
564 * @return {!TraceProvider} | 494 * @return {!TraceProvider} |
565 */ | 495 */ |
566 addTraceProvider: function(categoryName, categoryTooltip) | 496 addTraceProvider: function(categoryName, categoryTooltip) { |
567 { | 497 var id = 'extension-trace-provider-' + extensionServer.nextObjectId(); |
568 var id = "extension-trace-provider-" + extensionServer.nextObjectId(); | 498 extensionServer.sendRequest( |
569 extensionServer.sendRequest({ command: commands.AddTraceProvider, id: id
, categoryName: categoryName, categoryTooltip: categoryTooltip}); | 499 {command: commands.AddTraceProvider, id: id, categoryName: categoryNam
e, categoryTooltip: categoryTooltip}); |
570 return new TraceProvider(id); | 500 return new TraceProvider(id); |
571 } | 501 } |
572 }; | 502 }; |
573 | 503 |
574 /** | 504 /** |
575 * @constructor | 505 * @constructor |
576 * @param {string} id | 506 * @param {string} id |
577 */ | 507 */ |
578 function TraceProvider(id) | 508 function TraceProvider(id) { |
579 { | |
580 this.onRecordingStarted = new EventSink(events.RecordingStarted + id); | 509 this.onRecordingStarted = new EventSink(events.RecordingStarted + id); |
581 this.onRecordingStopped = new EventSink(events.RecordingStopped + id); | 510 this.onRecordingStopped = new EventSink(events.RecordingStopped + id); |
582 } | 511 } |
583 | 512 |
584 /** | 513 /** |
585 * @constructor | 514 * @constructor |
586 */ | 515 */ |
587 function Audits() | 516 function Audits() { |
588 { | 517 } |
589 } | 518 |
590 | 519 Audits.prototype = { |
591 Audits.prototype = { | |
592 /** | 520 /** |
593 * @return {!AuditCategory} | 521 * @return {!AuditCategory} |
594 */ | 522 */ |
595 addCategory: function(displayName, resultCount) | 523 addCategory: function(displayName, resultCount) { |
596 { | 524 var id = 'extension-audit-category-' + extensionServer.nextObjectId(); |
597 var id = "extension-audit-category-" + extensionServer.nextObjectId(); | 525 if (typeof resultCount !== 'undefined') |
598 if (typeof resultCount !== "undefined") | 526 console.warn( |
599 console.warn("Passing resultCount to audits.addCategory() is depreca
ted. Use AuditResult.updateProgress() instead."); | 527 'Passing resultCount to audits.addCategory() is deprecated. Use Audi
tResult.updateProgress() instead.'); |
600 extensionServer.sendRequest({ command: commands.AddAuditCategory, id: id
, displayName: displayName, resultCount: resultCount }); | 528 extensionServer.sendRequest( |
601 return new AuditCategory(id); | 529 {command: commands.AddAuditCategory, id: id, displayName: displayName,
resultCount: resultCount}); |
602 } | 530 return new AuditCategory(id); |
603 }; | 531 } |
604 | 532 }; |
605 /** | 533 |
606 * @constructor | 534 /** |
607 */ | 535 * @constructor |
608 function AuditCategoryImpl(id) | 536 */ |
609 { | 537 function AuditCategoryImpl(id) { |
610 /** | 538 /** |
611 * @this {EventSinkImpl} | 539 * @this {EventSinkImpl} |
612 */ | 540 */ |
613 function dispatchAuditEvent(request) | 541 function dispatchAuditEvent(request) { |
614 { | 542 var auditResult = new AuditResult(request.arguments[0]); |
615 var auditResult = new AuditResult(request.arguments[0]); | 543 try { |
616 try { | 544 this._fire(auditResult); |
617 this._fire(auditResult); | 545 } catch (e) { |
618 } catch (e) { | 546 console.error('Uncaught exception in extension audit event handler: ' +
e); |
619 console.error("Uncaught exception in extension audit event handler:
" + e); | 547 auditResult.done(); |
620 auditResult.done(); | 548 } |
621 } | |
622 } | 549 } |
623 this._id = id; | 550 this._id = id; |
624 this.onAuditStarted = new EventSink(events.AuditStarted + id, dispatchAuditE
vent); | 551 this.onAuditStarted = new EventSink(events.AuditStarted + id, dispatchAuditE
vent); |
625 } | 552 } |
626 | 553 |
627 /** | 554 /** |
628 * @constructor | 555 * @constructor |
629 */ | 556 */ |
630 function AuditResultImpl(id) | 557 function AuditResultImpl(id) { |
631 { | |
632 this._id = id; | 558 this._id = id; |
633 | 559 |
634 this.createURL = this._nodeFactory.bind(this, "url"); | 560 this.createURL = this._nodeFactory.bind(this, 'url'); |
635 this.createSnippet = this._nodeFactory.bind(this, "snippet"); | 561 this.createSnippet = this._nodeFactory.bind(this, 'snippet'); |
636 this.createText = this._nodeFactory.bind(this, "text"); | 562 this.createText = this._nodeFactory.bind(this, 'text'); |
637 this.createObject = this._nodeFactory.bind(this, "object"); | 563 this.createObject = this._nodeFactory.bind(this, 'object'); |
638 this.createNode = this._nodeFactory.bind(this, "node"); | 564 this.createNode = this._nodeFactory.bind(this, 'node'); |
639 } | 565 } |
640 | 566 |
641 AuditResultImpl.prototype = { | 567 AuditResultImpl.prototype = { |
642 addResult: function(displayName, description, severity, details) | 568 addResult: function(displayName, description, severity, details) { |
643 { | 569 // shorthand for specifying details directly in addResult(). |
644 // shorthand for specifying details directly in addResult(). | 570 if (details && !(details instanceof AuditResultNode)) |
645 if (details && !(details instanceof AuditResultNode)) | 571 details = new AuditResultNode(Array.isArray(details) ? details : [detail
s]); |
646 details = new AuditResultNode(Array.isArray(details) ? details : [de
tails]); | 572 |
647 | 573 var request = { |
648 var request = { | 574 command: commands.AddAuditResult, |
649 command: commands.AddAuditResult, | 575 resultId: this._id, |
650 resultId: this._id, | 576 displayName: displayName, |
651 displayName: displayName, | 577 description: description, |
652 description: description, | 578 severity: severity, |
653 severity: severity, | 579 details: details |
654 details: details | 580 }; |
655 }; | 581 extensionServer.sendRequest(request); |
656 extensionServer.sendRequest(request); | |
657 }, | 582 }, |
658 | 583 |
659 /** | 584 /** |
660 * @return {!Object} | 585 * @return {!Object} |
661 */ | 586 */ |
662 createResult: function() | 587 createResult: function() { |
663 { | 588 return new AuditResultNode(Array.prototype.slice.call(arguments)); |
664 return new AuditResultNode(Array.prototype.slice.call(arguments)); | 589 }, |
665 }, | 590 |
666 | 591 updateProgress: function(worked, totalWork) { |
667 updateProgress: function(worked, totalWork) | 592 extensionServer.sendRequest( |
668 { | 593 {command: commands.UpdateAuditProgress, resultId: this._id, progress:
worked / totalWork}); |
669 extensionServer.sendRequest({ command: commands.UpdateAuditProgress, res
ultId: this._id, progress: worked / totalWork }); | 594 }, |
670 }, | 595 |
671 | 596 done: function() { |
672 done: function() | 597 extensionServer.sendRequest({command: commands.StopAuditCategoryRun, resul
tId: this._id}); |
673 { | |
674 extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, re
sultId: this._id }); | |
675 }, | 598 }, |
676 | 599 |
677 /** | 600 /** |
678 * @type {!Object.<string, string>} | 601 * @type {!Object.<string, string>} |
679 */ | 602 */ |
680 get Severity() | 603 get Severity() { |
681 { | 604 return apiPrivate.audits.Severity; |
682 return apiPrivate.audits.Severity; | |
683 }, | 605 }, |
684 | 606 |
685 /** | 607 /** |
686 * @return {!{type: string, arguments: !Array.<string|number>}} | 608 * @return {!{type: string, arguments: !Array.<string|number>}} |
687 */ | 609 */ |
688 createResourceLink: function(url, lineNumber) | 610 createResourceLink: function(url, lineNumber) { |
689 { | 611 return {type: 'resourceLink', arguments: [url, lineNumber && lineNumber -
1]}; |
690 return { | |
691 type: "resourceLink", | |
692 arguments: [url, lineNumber && lineNumber - 1] | |
693 }; | |
694 }, | 612 }, |
695 | 613 |
696 /** | 614 /** |
697 * @return {!{type: string, arguments: !Array.<string|number>}} | 615 * @return {!{type: string, arguments: !Array.<string|number>}} |
698 */ | 616 */ |
699 _nodeFactory: function(type) | 617 _nodeFactory: function(type) { |
700 { | 618 return {type: type, arguments: Array.prototype.slice.call(arguments, 1)}; |
701 return { | 619 } |
702 type: type, | 620 }; |
703 arguments: Array.prototype.slice.call(arguments, 1) | 621 |
704 }; | 622 /** |
705 } | 623 * @constructor |
706 }; | 624 */ |
707 | 625 function AuditResultNode(contents) { |
708 /** | |
709 * @constructor | |
710 */ | |
711 function AuditResultNode(contents) | |
712 { | |
713 this.contents = contents; | 626 this.contents = contents; |
714 this.children = []; | 627 this.children = []; |
715 this.expanded = false; | 628 this.expanded = false; |
716 } | 629 } |
717 | 630 |
718 AuditResultNode.prototype = { | 631 AuditResultNode.prototype = { |
719 /** | 632 /** |
720 * @return {!Object} | 633 * @return {!Object} |
721 */ | 634 */ |
722 addChild: function() | 635 addChild: function() { |
723 { | 636 var node = new AuditResultNode(Array.prototype.slice.call(arguments)); |
724 var node = new AuditResultNode(Array.prototype.slice.call(arguments)); | 637 this.children.push(node); |
725 this.children.push(node); | 638 return node; |
726 return node; | 639 } |
727 } | 640 }; |
728 }; | 641 |
729 | 642 /** |
730 /** | 643 * @constructor |
731 * @constructor | 644 */ |
732 */ | 645 function InspectedWindow() { |
733 function InspectedWindow() | |
734 { | |
735 /** | 646 /** |
736 * @this {EventSinkImpl} | 647 * @this {EventSinkImpl} |
737 */ | 648 */ |
738 function dispatchResourceEvent(message) | 649 function dispatchResourceEvent(message) { |
739 { | 650 this._fire(new Resource(message.arguments[0])); |
740 this._fire(new Resource(message.arguments[0])); | |
741 } | 651 } |
742 | 652 |
743 /** | 653 /** |
744 * @this {EventSinkImpl} | 654 * @this {EventSinkImpl} |
745 */ | 655 */ |
746 function dispatchResourceContentEvent(message) | 656 function dispatchResourceContentEvent(message) { |
747 { | 657 this._fire(new Resource(message.arguments[0]), message.arguments[1]); |
748 this._fire(new Resource(message.arguments[0]), message.arguments[1]); | |
749 } | 658 } |
750 | 659 |
751 this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceE
vent); | 660 this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceE
vent); |
752 this.onResourceContentCommitted = new EventSink(events.ResourceContentCommit
ted, dispatchResourceContentEvent); | 661 this.onResourceContentCommitted = new EventSink(events.ResourceContentCommit
ted, dispatchResourceContentEvent); |
753 } | 662 } |
754 | 663 |
755 InspectedWindow.prototype = { | 664 InspectedWindow.prototype = { |
756 reload: function(optionsOrUserAgent) | 665 reload: function(optionsOrUserAgent) { |
757 { | 666 var options = null; |
758 var options = null; | 667 if (typeof optionsOrUserAgent === 'object') { |
759 if (typeof optionsOrUserAgent === "object") { | 668 options = optionsOrUserAgent; |
760 options = optionsOrUserAgent; | 669 } else if (typeof optionsOrUserAgent === 'string') { |
761 } else if (typeof optionsOrUserAgent === "string") { | 670 options = {userAgent: optionsOrUserAgent}; |
762 options = { userAgent: optionsOrUserAgent }; | 671 console.warn( |
763 console.warn("Passing userAgent as string parameter to inspectedWind
ow.reload() is deprecated. " + | 672 'Passing userAgent as string parameter to inspectedWindow.reload() i
s deprecated. ' + |
764 "Use inspectedWindow.reload({ userAgent: value}) instea
d."); | 673 'Use inspectedWindow.reload({ userAgent: value}) instead.'); |
765 } | 674 } |
766 extensionServer.sendRequest({ command: commands.Reload, options: options
}); | 675 extensionServer.sendRequest({command: commands.Reload, options: options}); |
767 }, | 676 }, |
768 | 677 |
769 /** | 678 /** |
770 * @return {?Object} | 679 * @return {?Object} |
771 */ | 680 */ |
772 eval: function(expression, evaluateOptions) | 681 eval: function(expression, evaluateOptions) { |
773 { | 682 var callback = extractCallbackArgument(arguments); |
774 var callback = extractCallbackArgument(arguments); | 683 function callbackWrapper(result) { |
775 function callbackWrapper(result) | 684 if (result.isError || result.isException) |
776 { | 685 callback(undefined, result); |
777 if (result.isError || result.isException) | 686 else |
778 callback(undefined, result); | 687 callback(result.value); |
779 else | 688 } |
780 callback(result.value); | 689 var request = {command: commands.EvaluateOnInspectedPage, expression: expr
ession}; |
781 } | 690 if (typeof evaluateOptions === 'object') |
782 var request = { | 691 request.evaluateOptions = evaluateOptions; |
783 command: commands.EvaluateOnInspectedPage, | 692 extensionServer.sendRequest(request, callback && callbackWrapper); |
784 expression: expression | 693 return null; |
785 }; | 694 }, |
786 if (typeof evaluateOptions === "object") | 695 |
787 request.evaluateOptions = evaluateOptions; | 696 getResources: function(callback) { |
788 extensionServer.sendRequest(request, callback && callbackWrapper); | 697 function wrapResource(resourceData) { |
789 return null; | 698 return new Resource(resourceData); |
790 }, | 699 } |
791 | 700 function callbackWrapper(resources) { |
792 getResources: function(callback) | 701 callback(resources.map(wrapResource)); |
793 { | 702 } |
794 function wrapResource(resourceData) | 703 extensionServer.sendRequest({command: commands.GetPageResources}, callback
&& callbackWrapper); |
795 { | 704 } |
796 return new Resource(resourceData); | 705 }; |
797 } | 706 |
798 function callbackWrapper(resources) | 707 /** |
799 { | 708 * @constructor |
800 callback(resources.map(wrapResource)); | 709 */ |
801 } | 710 function ResourceImpl(resourceData) { |
802 extensionServer.sendRequest({ command: commands.GetPageResources }, call
back && callbackWrapper); | |
803 } | |
804 }; | |
805 | |
806 /** | |
807 * @constructor | |
808 */ | |
809 function ResourceImpl(resourceData) | |
810 { | |
811 this._url = resourceData.url; | 711 this._url = resourceData.url; |
812 this._type = resourceData.type; | 712 this._type = resourceData.type; |
813 } | 713 } |
814 | 714 |
815 ResourceImpl.prototype = { | 715 ResourceImpl.prototype = { |
816 get url() | 716 get url() { |
817 { | 717 return this._url; |
818 return this._url; | 718 }, |
819 }, | 719 |
820 | 720 get type() { |
821 get type() | 721 return this._type; |
822 { | 722 }, |
823 return this._type; | 723 |
824 }, | 724 getContent: function(callback) { |
825 | 725 function callbackWrapper(response) { |
826 getContent: function(callback) | 726 callback(response.content, response.encoding); |
827 { | 727 } |
828 function callbackWrapper(response) | 728 |
829 { | 729 extensionServer.sendRequest({command: commands.GetResourceContent, url: th
is._url}, callback && callbackWrapper); |
830 callback(response.content, response.encoding); | 730 }, |
831 } | 731 |
832 | 732 setContent: function(content, commit, callback) { |
833 extensionServer.sendRequest({ command: commands.GetResourceContent, url:
this._url }, callback && callbackWrapper); | 733 extensionServer.sendRequest( |
834 }, | 734 {command: commands.SetResourceContent, url: this._url, content: conten
t, commit: commit}, callback); |
835 | 735 } |
836 setContent: function(content, commit, callback) | 736 }; |
837 { | 737 |
838 extensionServer.sendRequest({ command: commands.SetResourceContent, url:
this._url, content: content, commit: commit }, callback); | 738 function getTabId() { |
839 } | |
840 }; | |
841 | |
842 function getTabId() | |
843 { | |
844 return inspectedTabId; | 739 return inspectedTabId; |
845 } | 740 } |
846 | 741 |
847 var keyboardEventRequestQueue = []; | 742 var keyboardEventRequestQueue = []; |
848 var forwardTimer = null; | 743 var forwardTimer = null; |
849 | 744 |
850 function forwardKeyboardEvent(event) | 745 function forwardKeyboardEvent(event) { |
851 { | |
852 // We only care about global hotkeys, not about random text | 746 // We only care about global hotkeys, not about random text |
853 if (!event.ctrlKey && !event.altKey && !event.metaKey && !/^F\d+$/.test(even
t.key) && event.key !== "Escape") | 747 if (!event.ctrlKey && !event.altKey && !event.metaKey && !/^F\d+$/.test(even
t.key) && event.key !== 'Escape') |
854 return; | 748 return; |
855 var requestPayload = { | 749 var requestPayload = { |
856 eventType: event.type, | 750 eventType: event.type, |
857 ctrlKey: event.ctrlKey, | 751 ctrlKey: event.ctrlKey, |
858 altKey: event.altKey, | 752 altKey: event.altKey, |
859 metaKey: event.metaKey, | 753 metaKey: event.metaKey, |
860 keyIdentifier: event.keyIdentifier, | 754 keyIdentifier: event.keyIdentifier, |
861 key: event.key, | 755 key: event.key, |
862 code: event.code, | 756 code: event.code, |
863 location: event.location, | 757 location: event.location, |
864 keyCode: event.keyCode | 758 keyCode: event.keyCode |
865 }; | 759 }; |
866 keyboardEventRequestQueue.push(requestPayload); | 760 keyboardEventRequestQueue.push(requestPayload); |
867 if (!forwardTimer) | 761 if (!forwardTimer) |
868 forwardTimer = setTimeout(forwardEventQueue, 0); | 762 forwardTimer = setTimeout(forwardEventQueue, 0); |
869 } | 763 } |
870 | 764 |
871 function forwardEventQueue() | 765 function forwardEventQueue() { |
872 { | |
873 forwardTimer = null; | 766 forwardTimer = null; |
874 var request = { | 767 var request = {command: commands.ForwardKeyboardEvent, entries: keyboardEven
tRequestQueue}; |
875 command: commands.ForwardKeyboardEvent, | |
876 entries: keyboardEventRequestQueue | |
877 }; | |
878 extensionServer.sendRequest(request); | 768 extensionServer.sendRequest(request); |
879 keyboardEventRequestQueue = []; | 769 keyboardEventRequestQueue = []; |
880 } | 770 } |
881 | 771 |
882 document.addEventListener("keydown", forwardKeyboardEvent, false); | 772 document.addEventListener('keydown', forwardKeyboardEvent, false); |
883 document.addEventListener("keypress", forwardKeyboardEvent, false); | 773 document.addEventListener('keypress', forwardKeyboardEvent, false); |
884 | 774 |
885 /** | 775 /** |
886 * @constructor | 776 * @constructor |
887 */ | 777 */ |
888 function ExtensionServerClient() | 778 function ExtensionServerClient() { |
889 { | |
890 this._callbacks = {}; | 779 this._callbacks = {}; |
891 this._handlers = {}; | 780 this._handlers = {}; |
892 this._lastRequestId = 0; | 781 this._lastRequestId = 0; |
893 this._lastObjectId = 0; | 782 this._lastObjectId = 0; |
894 | 783 |
895 this.registerHandler("callback", this._onCallback.bind(this)); | 784 this.registerHandler('callback', this._onCallback.bind(this)); |
896 | 785 |
897 var channel = new MessageChannel(); | 786 var channel = new MessageChannel(); |
898 this._port = channel.port1; | 787 this._port = channel.port1; |
899 this._port.addEventListener("message", this._onMessage.bind(this), false); | 788 this._port.addEventListener('message', this._onMessage.bind(this), false); |
900 this._port.start(); | 789 this._port.start(); |
901 | 790 |
902 window.parent.postMessage("registerExtension", "*", [ channel.port2 ]); | 791 window.parent.postMessage('registerExtension', '*', [channel.port2]); |
903 } | 792 } |
904 | 793 |
905 ExtensionServerClient.prototype = { | 794 ExtensionServerClient.prototype = { |
906 /** | 795 /** |
907 * @param {!Object} message | 796 * @param {!Object} message |
908 * @param {function()=} callback | 797 * @param {function()=} callback |
909 */ | 798 */ |
910 sendRequest: function(message, callback) | 799 sendRequest: function(message, callback) { |
911 { | 800 if (typeof callback === 'function') |
912 if (typeof callback === "function") | 801 message.requestId = this._registerCallback(callback); |
913 message.requestId = this._registerCallback(callback); | 802 this._port.postMessage(message); |
914 this._port.postMessage(message); | |
915 }, | 803 }, |
916 | 804 |
917 /** | 805 /** |
918 * @return {boolean} | 806 * @return {boolean} |
919 */ | 807 */ |
920 hasHandler: function(command) | 808 hasHandler: function(command) { |
921 { | 809 return !!this._handlers[command]; |
922 return !!this._handlers[command]; | 810 }, |
923 }, | 811 |
924 | 812 registerHandler: function(command, handler) { |
925 registerHandler: function(command, handler) | 813 this._handlers[command] = handler; |
926 { | 814 }, |
927 this._handlers[command] = handler; | 815 |
928 }, | 816 unregisterHandler: function(command) { |
929 | 817 delete this._handlers[command]; |
930 unregisterHandler: function(command) | |
931 { | |
932 delete this._handlers[command]; | |
933 }, | 818 }, |
934 | 819 |
935 /** | 820 /** |
936 * @return {string} | 821 * @return {string} |
937 */ | 822 */ |
938 nextObjectId: function() | 823 nextObjectId: function() { |
939 { | 824 return injectedScriptId.toString() + '_' + ++this._lastObjectId; |
940 return injectedScriptId.toString() + "_" + ++this._lastObjectId; | 825 }, |
941 }, | 826 |
942 | 827 _registerCallback: function(callback) { |
943 _registerCallback: function(callback) | 828 var id = ++this._lastRequestId; |
944 { | 829 this._callbacks[id] = callback; |
945 var id = ++this._lastRequestId; | 830 return id; |
946 this._callbacks[id] = callback; | 831 }, |
947 return id; | 832 |
948 }, | 833 _onCallback: function(request) { |
949 | 834 if (request.requestId in this._callbacks) { |
950 _onCallback: function(request) | 835 var callback = this._callbacks[request.requestId]; |
951 { | 836 delete this._callbacks[request.requestId]; |
952 if (request.requestId in this._callbacks) { | 837 callback(request.result); |
953 var callback = this._callbacks[request.requestId]; | 838 } |
954 delete this._callbacks[request.requestId]; | 839 }, |
955 callback(request.result); | 840 |
956 } | 841 _onMessage: function(event) { |
957 }, | 842 var request = event.data; |
958 | 843 var handler = this._handlers[request.command]; |
959 _onMessage: function(event) | 844 if (handler) |
960 { | 845 handler.call(this, request); |
961 var request = event.data; | 846 } |
962 var handler = this._handlers[request.command]; | 847 }; |
963 if (handler) | 848 |
964 handler.call(this, request); | 849 function populateInterfaceClass(interfaze, implementation) { |
965 } | |
966 }; | |
967 | |
968 function populateInterfaceClass(interfaze, implementation) | |
969 { | |
970 for (var member in implementation) { | 850 for (var member in implementation) { |
971 if (member.charAt(0) === "_") | 851 if (member.charAt(0) === '_') |
972 continue; | 852 continue; |
973 var descriptor = null; | 853 var descriptor = null; |
974 // Traverse prototype chain until we find the owner. | 854 // Traverse prototype chain until we find the owner. |
975 for (var owner = implementation; owner && !descriptor; owner = owner.__p
roto__) | 855 for (var owner = implementation; owner && !descriptor; owner = owner.__pro
to__) |
976 descriptor = Object.getOwnPropertyDescriptor(owner, member); | 856 descriptor = Object.getOwnPropertyDescriptor(owner, member); |
977 if (!descriptor) | 857 if (!descriptor) |
978 continue; | 858 continue; |
979 if (typeof descriptor.value === "function") | 859 if (typeof descriptor.value === 'function') |
980 interfaze[member] = descriptor.value.bind(implementation); | 860 interfaze[member] = descriptor.value.bind(implementation); |
981 else if (typeof descriptor.get === "function") | 861 else if (typeof descriptor.get === 'function') |
982 interfaze.__defineGetter__(member, descriptor.get.bind(implementatio
n)); | 862 interfaze.__defineGetter__(member, descriptor.get.bind(implementation)); |
983 else | 863 else |
984 Object.defineProperty(interfaze, member, descriptor); | 864 Object.defineProperty(interfaze, member, descriptor); |
985 } | 865 } |
986 } | 866 } |
987 | 867 |
988 var extensionServer = new ExtensionServerClient(); | 868 var extensionServer = new ExtensionServerClient(); |
989 var coreAPI = new InspectorExtensionAPI(); | 869 var coreAPI = new InspectorExtensionAPI(); |
990 | 870 |
991 var chrome = window.chrome || {}; | 871 var chrome = window.chrome || {}; |
992 // Override chrome.devtools as a workaround for a error-throwing getter being ex
posed | 872 // Override chrome.devtools as a workaround for a error-throwing getter being
exposed |
993 // in extension pages loaded into a non-extension process (only happens for remo
te client | 873 // in extension pages loaded into a non-extension process (only happens for re
mote client |
994 // extensions) | 874 // extensions) |
995 var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools"); | 875 var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, 'devtools'); |
996 if (!devtools_descriptor || devtools_descriptor.get) | 876 if (!devtools_descriptor || devtools_descriptor.get) |
997 Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true }); | 877 Object.defineProperty(chrome, 'devtools', {value: {}, enumerable: true}); |
998 | 878 |
999 // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspec
tedWindow. | 879 // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.insp
ectedWindow. |
1000 chrome.devtools.inspectedWindow = {}; | 880 chrome.devtools.inspectedWindow = {}; |
1001 chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId); | 881 chrome.devtools.inspectedWindow.__defineGetter__('tabId', getTabId); |
1002 chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow; | 882 chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow; |
1003 chrome.devtools.network = coreAPI.network; | 883 chrome.devtools.network = coreAPI.network; |
1004 chrome.devtools.panels = coreAPI.panels; | 884 chrome.devtools.panels = coreAPI.panels; |
1005 chrome.devtools.panels.themeName = themeName; | 885 chrome.devtools.panels.themeName = themeName; |
1006 | 886 |
1007 // default to expose experimental APIs for now. | 887 // default to expose experimental APIs for now. |
1008 if (extensionInfo.exposeExperimentalAPIs !== false) { | 888 if (extensionInfo.exposeExperimentalAPIs !== false) { |
1009 chrome.experimental = chrome.experimental || {}; | 889 chrome.experimental = chrome.experimental || {}; |
1010 chrome.experimental.devtools = chrome.experimental.devtools || {}; | 890 chrome.experimental.devtools = chrome.experimental.devtools || {}; |
1011 | 891 |
1012 var properties = Object.getOwnPropertyNames(coreAPI); | 892 var properties = Object.getOwnPropertyNames(coreAPI); |
1013 for (var i = 0; i < properties.length; ++i) { | 893 for (var i = 0; i < properties.length; ++i) { |
1014 var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i])
; | 894 var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]); |
1015 if (descriptor) | 895 if (descriptor) |
1016 Object.defineProperty(chrome.experimental.devtools, properties[i], d
escriptor); | 896 Object.defineProperty(chrome.experimental.devtools, properties[i], descr
iptor); |
1017 } | 897 } |
1018 chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWind
ow; | 898 chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWind
ow; |
| 899 } |
| 900 |
| 901 if (extensionInfo.exposeWebInspectorNamespace) |
| 902 window.webInspector = coreAPI; |
| 903 testHook(extensionServer, coreAPI); |
1019 } | 904 } |
1020 | 905 |
1021 if (extensionInfo.exposeWebInspectorNamespace) | |
1022 window.webInspector = coreAPI; | |
1023 testHook(extensionServer, coreAPI); | |
1024 } | |
1025 | |
1026 /** | 906 /** |
1027 * @param {!ExtensionDescriptor} extensionInfo | 907 * @param {!ExtensionDescriptor} extensionInfo |
1028 * @param {string} inspectedTabId | 908 * @param {string} inspectedTabId |
1029 * @param {string} themeName | 909 * @param {string} themeName |
1030 * @param {function(!Object, !Object)|undefined} testHook | 910 * @param {function(!Object, !Object)|undefined} testHook |
1031 * @return {string} | 911 * @return {string} |
1032 */ | 912 */ |
1033 function buildExtensionAPIInjectedScript(extensionInfo, inspectedTabId, themeNam
e, testHook) | 913 function buildExtensionAPIInjectedScript(extensionInfo, inspectedTabId, themeNam
e, testHook) { |
1034 { | 914 var argumentsJSON = [extensionInfo, inspectedTabId || null, themeName].map(_ =
> JSON.stringify(_)).join(','); |
1035 var argumentsJSON = [extensionInfo, inspectedTabId || null, themeName].map(_
=> JSON.stringify(_)).join(","); | 915 if (!testHook) |
1036 if (!testHook) | 916 testHook = () => {}; |
1037 testHook = () => {}; | 917 return '(function(injectedScriptId){ ' + defineCommonExtensionSymbols.toString
() + ';' + |
1038 return "(function(injectedScriptId){ " + | 918 '(' + injectedExtensionAPI.toString() + ')(' + argumentsJSON + ',' + testH
ook + ', injectedScriptId);' + |
1039 defineCommonExtensionSymbols.toString() + ";" + | 919 '})'; |
1040 "(" + injectedExtensionAPI.toString() + ")(" + argumentsJSON + "," + tes
tHook + ", injectedScriptId);" + | |
1041 "})"; | |
1042 } | 920 } |
OLD | NEW |