OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Custom bindings for the webRequest API. | 5 // Custom bindings for the webRequest API. |
6 | 6 |
7 (function() { | 7 (function() { |
8 | 8 |
9 native function GetChromeHidden(); | 9 native function GetChromeHidden(); |
10 native function GetUniqueSubEventName(eventName); | 10 native function GetUniqueSubEventName(eventName); |
11 | 11 |
12 var chromeHidden = GetChromeHidden(); | 12 var chromeHidden = GetChromeHidden(); |
13 | 13 |
14 // WebRequestEvent object. This is used for special webRequest events with | 14 // WebRequestEvent object. This is used for special webRequest events with |
15 // extra parameters. Each invocation of addListener creates a new named | 15 // extra parameters. Each invocation of addListener creates a new named |
16 // sub-event. That sub-event is associated with the extra parameters in the | 16 // sub-event. That sub-event is associated with the extra parameters in the |
17 // browser process, so that only it is dispatched when the main event occurs | 17 // browser process, so that only it is dispatched when the main event occurs |
18 // matching the extra parameters. | 18 // matching the extra parameters. |
19 // | 19 // |
20 // Example: | 20 // Example: |
21 // chrome.webRequest.onBeforeRequest.addListener( | 21 // chrome.webRequest.onBeforeRequest.addListener( |
22 // callback, {urls: "http://*.google.com/*"}); | 22 // callback, {urls: 'http://*.google.com/*'}); |
23 // ^ callback will only be called for onBeforeRequests matching the filter. | 23 // ^ callback will only be called for onBeforeRequests matching the filter. |
24 function WebRequestEvent(eventName, opt_argSchemas, opt_extraArgSchemas, | 24 function WebRequestEvent(eventName, opt_argSchemas, opt_extraArgSchemas, |
25 opt_eventOptions) { | 25 opt_eventOptions) { |
26 if (typeof eventName != "string") | 26 if (typeof eventName != 'string') |
27 throw new Error("chrome.WebRequestEvent requires an event name."); | 27 throw new Error('chrome.WebRequestEvent requires an event name.'); |
28 | 28 |
29 this.eventName_ = eventName; | 29 this.eventName_ = eventName; |
30 this.argSchemas_ = opt_argSchemas; | 30 this.argSchemas_ = opt_argSchemas; |
31 this.extraArgSchemas_ = opt_extraArgSchemas; | 31 this.extraArgSchemas_ = opt_extraArgSchemas; |
32 this.subEvents_ = []; | 32 this.subEvents_ = []; |
33 this.eventOptions_ = opt_eventOptions || | 33 this.eventOptions_ = opt_eventOptions || |
34 {"supportsListeners": true, "supportsRules": false}; | 34 {'supportsListeners': true, 'supportsRules': false}; |
35 | 35 |
36 if (this.eventOptions_.supportsRules) | 36 if (this.eventOptions_.supportsRules) |
37 this.eventForRules_ = | 37 this.eventForRules_ = |
38 new chrome.Event(eventName, opt_argSchemas, opt_eventOptions); | 38 new chrome.Event(eventName, opt_argSchemas, opt_eventOptions); |
39 }; | 39 }; |
40 | 40 |
41 // Test if the given callback is registered for this event. | 41 // Test if the given callback is registered for this event. |
42 WebRequestEvent.prototype.hasListener = function(cb) { | 42 WebRequestEvent.prototype.hasListener = function(cb) { |
43 if (!this.eventOptions_.supportsListeners) | 43 if (!this.eventOptions_.supportsListeners) |
44 throw new Error("This event does not support listeners."); | 44 throw new Error('This event does not support listeners.'); |
45 return this.findListener_(cb) > -1; | 45 return this.findListener_(cb) > -1; |
46 }; | 46 }; |
47 | 47 |
48 // Test if any callbacks are registered fur thus event. | 48 // Test if any callbacks are registered fur thus event. |
49 WebRequestEvent.prototype.hasListeners = function() { | 49 WebRequestEvent.prototype.hasListeners = function() { |
50 if (!this.eventOptions_.supportsListeners) | 50 if (!this.eventOptions_.supportsListeners) |
51 throw new Error("This event does not support listeners."); | 51 throw new Error('This event does not support listeners.'); |
52 return this.subEvents_.length > 0; | 52 return this.subEvents_.length > 0; |
53 }; | 53 }; |
54 | 54 |
55 // Registers a callback to be called when this event is dispatched. If | 55 // Registers a callback to be called when this event is dispatched. If |
56 // opt_filter is specified, then the callback is only called for events that | 56 // opt_filter is specified, then the callback is only called for events that |
57 // match the given filters. If opt_extraInfo is specified, the given optional | 57 // match the given filters. If opt_extraInfo is specified, the given optional |
58 // info is sent to the callback. | 58 // info is sent to the callback. |
59 WebRequestEvent.prototype.addListener = | 59 WebRequestEvent.prototype.addListener = |
60 function(cb, opt_filter, opt_extraInfo) { | 60 function(cb, opt_filter, opt_extraInfo) { |
61 if (!this.eventOptions_.supportsListeners) | 61 if (!this.eventOptions_.supportsListeners) |
62 throw new Error("This event does not support listeners."); | 62 throw new Error('This event does not support listeners.'); |
63 var subEventName = GetUniqueSubEventName(this.eventName_); | 63 var subEventName = GetUniqueSubEventName(this.eventName_); |
64 // Note: this could fail to validate, in which case we would not add the | 64 // Note: this could fail to validate, in which case we would not add the |
65 // subEvent listener. | 65 // subEvent listener. |
66 chromeHidden.validate(Array.prototype.slice.call(arguments, 1), | 66 chromeHidden.validate(Array.prototype.slice.call(arguments, 1), |
67 this.extraArgSchemas_); | 67 this.extraArgSchemas_); |
68 chrome.webRequest.addEventListener( | 68 chrome.webRequest.addEventListener( |
69 cb, opt_filter, opt_extraInfo, this.eventName_, subEventName); | 69 cb, opt_filter, opt_extraInfo, this.eventName_, subEventName); |
70 | 70 |
71 var subEvent = new chrome.Event(subEventName, this.argSchemas_); | 71 var subEvent = new chrome.Event(subEventName, this.argSchemas_); |
72 var subEventCallback = cb; | 72 var subEventCallback = cb; |
73 if (opt_extraInfo && opt_extraInfo.indexOf("blocking") >= 0) { | 73 if (opt_extraInfo && opt_extraInfo.indexOf('blocking') >= 0) { |
74 var eventName = this.eventName_; | 74 var eventName = this.eventName_; |
75 subEventCallback = function() { | 75 subEventCallback = function() { |
76 var requestId = arguments[0].requestId; | 76 var requestId = arguments[0].requestId; |
77 try { | 77 try { |
78 var result = cb.apply(null, arguments); | 78 var result = cb.apply(null, arguments); |
79 chrome.webRequest.eventHandled( | 79 chrome.webRequest.eventHandled( |
80 eventName, subEventName, requestId, result); | 80 eventName, subEventName, requestId, result); |
81 } catch (e) { | 81 } catch (e) { |
82 chrome.webRequest.eventHandled( | 82 chrome.webRequest.eventHandled( |
83 eventName, subEventName, requestId); | 83 eventName, subEventName, requestId); |
84 throw e; | 84 throw e; |
85 } | 85 } |
86 }; | 86 }; |
87 } else if (opt_extraInfo && opt_extraInfo.indexOf("asyncBlocking") >= 0) { | 87 } else if (opt_extraInfo && opt_extraInfo.indexOf('asyncBlocking') >= 0) { |
88 var eventName = this.eventName_; | 88 var eventName = this.eventName_; |
89 subEventCallback = function() { | 89 subEventCallback = function() { |
90 var details = arguments[0]; | 90 var details = arguments[0]; |
91 var requestId = details.requestId; | 91 var requestId = details.requestId; |
92 var handledCallback = function(response) { | 92 var handledCallback = function(response) { |
93 chrome.webRequest.eventHandled( | 93 chrome.webRequest.eventHandled( |
94 eventName, subEventName, requestId, response); | 94 eventName, subEventName, requestId, response); |
95 }; | 95 }; |
96 cb.apply(null, [details, handledCallback]); | 96 cb.apply(null, [details, handledCallback]); |
97 }; | 97 }; |
98 } | 98 } |
99 this.subEvents_.push( | 99 this.subEvents_.push( |
100 {subEvent: subEvent, callback: cb, subEventCallback: subEventCallback}); | 100 {subEvent: subEvent, callback: cb, subEventCallback: subEventCallback}); |
101 subEvent.addListener(subEventCallback); | 101 subEvent.addListener(subEventCallback); |
102 }; | 102 }; |
103 | 103 |
104 // Unregisters a callback. | 104 // Unregisters a callback. |
105 WebRequestEvent.prototype.removeListener = function(cb) { | 105 WebRequestEvent.prototype.removeListener = function(cb) { |
106 if (!this.eventOptions_.supportsListeners) | 106 if (!this.eventOptions_.supportsListeners) |
107 throw new Error("This event does not support listeners."); | 107 throw new Error('This event does not support listeners.'); |
108 var idx; | 108 var idx; |
109 while ((idx = this.findListener_(cb)) >= 0) { | 109 while ((idx = this.findListener_(cb)) >= 0) { |
110 var e = this.subEvents_[idx]; | 110 var e = this.subEvents_[idx]; |
111 e.subEvent.removeListener(e.subEventCallback); | 111 e.subEvent.removeListener(e.subEventCallback); |
112 if (e.subEvent.hasListeners()) { | 112 if (e.subEvent.hasListeners()) { |
113 console.error( | 113 console.error( |
114 "Internal error: webRequest subEvent has orphaned listeners."); | 114 'Internal error: webRequest subEvent has orphaned listeners.'); |
115 } | 115 } |
116 this.subEvents_.splice(idx, 1); | 116 this.subEvents_.splice(idx, 1); |
117 } | 117 } |
118 }; | 118 }; |
119 | 119 |
120 WebRequestEvent.prototype.findListener_ = function(cb) { | 120 WebRequestEvent.prototype.findListener_ = function(cb) { |
121 for (var i in this.subEvents_) { | 121 for (var i in this.subEvents_) { |
122 var e = this.subEvents_[i]; | 122 var e = this.subEvents_[i]; |
123 if (e.callback === cb) { | 123 if (e.callback === cb) { |
124 if (e.subEvent.findListener_(e.subEventCallback) > -1) | 124 if (e.subEvent.findListener_(e.subEventCallback) > -1) |
125 return i; | 125 return i; |
126 console.error("Internal error: webRequest subEvent has no callback."); | 126 console.error('Internal error: webRequest subEvent has no callback.'); |
127 } | 127 } |
128 } | 128 } |
129 | 129 |
130 return -1; | 130 return -1; |
131 }; | 131 }; |
132 | 132 |
133 WebRequestEvent.prototype.addRules = function(rules, opt_cb) { | 133 WebRequestEvent.prototype.addRules = function(rules, opt_cb) { |
134 if (!this.eventOptions_.supportsRules) | 134 if (!this.eventOptions_.supportsRules) |
135 throw new Error("This event does not support rules."); | 135 throw new Error('This event does not support rules.'); |
136 this.eventForRules_.addRules(rules, opt_cb); | 136 this.eventForRules_.addRules(rules, opt_cb); |
137 } | 137 } |
138 | 138 |
139 WebRequestEvent.prototype.removeRules = function(ruleIdentifiers, opt_cb) { | 139 WebRequestEvent.prototype.removeRules = function(ruleIdentifiers, opt_cb) { |
140 if (!this.eventOptions_.supportsRules) | 140 if (!this.eventOptions_.supportsRules) |
141 throw new Error("This event does not support rules."); | 141 throw new Error('This event does not support rules.'); |
142 this.eventForRules_.removeRules(ruleIdentifiers, opt_cb); | 142 this.eventForRules_.removeRules(ruleIdentifiers, opt_cb); |
143 } | 143 } |
144 | 144 |
145 WebRequestEvent.prototype.getRules = function(ruleIdentifiers, cb) { | 145 WebRequestEvent.prototype.getRules = function(ruleIdentifiers, cb) { |
146 if (!this.eventOptions_.supportsRules) | 146 if (!this.eventOptions_.supportsRules) |
147 throw new Error("This event does not support rules."); | 147 throw new Error('This event does not support rules.'); |
148 this.eventForRules_.getRules(ruleIdentifiers, cb); | 148 this.eventForRules_.getRules(ruleIdentifiers, cb); |
149 } | 149 } |
150 | 150 |
151 chromeHidden.registerCustomEvent("webRequest", WebRequestEvent); | 151 chromeHidden.registerCustomEvent('webRequest', WebRequestEvent); |
152 | 152 |
153 chromeHidden.registerCustomHook("webRequest", function(api) { | 153 chromeHidden.registerCustomHook('webRequest', function(api) { |
154 var apiFunctions = api.apiFunctions; | 154 var apiFunctions = api.apiFunctions; |
155 var sendRequest = api.sendRequest; | 155 var sendRequest = api.sendRequest; |
156 | 156 |
157 apiFunctions.setHandleRequest("webRequest.addEventListener", | 157 apiFunctions.setHandleRequest('addEventListener', function() { |
158 function() { | |
159 var args = Array.prototype.slice.call(arguments); | 158 var args = Array.prototype.slice.call(arguments); |
160 sendRequest(this.name, args, this.definition.parameters, | 159 sendRequest(this.name, args, this.definition.parameters, |
161 {forIOThread: true}); | 160 {forIOThread: true}); |
162 }); | 161 }); |
163 | 162 |
164 apiFunctions.setHandleRequest("webRequest.eventHandled", | 163 apiFunctions.setHandleRequest('eventHandled', function() { |
165 function() { | |
166 var args = Array.prototype.slice.call(arguments); | 164 var args = Array.prototype.slice.call(arguments); |
167 sendRequest(this.name, args, this.definition.parameters, | 165 sendRequest(this.name, args, this.definition.parameters, |
168 {forIOThread: true}); | 166 {forIOThread: true}); |
169 }); | 167 }); |
170 | 168 |
171 apiFunctions.setHandleRequest("webRequest.handlerBehaviorChanged", | 169 apiFunctions.setHandleRequest('handlerBehaviorChanged', function() { |
172 function() { | |
173 var args = Array.prototype.slice.call(arguments); | 170 var args = Array.prototype.slice.call(arguments); |
174 sendRequest(this.name, args, this.definition.parameters, | 171 sendRequest(this.name, args, this.definition.parameters, |
175 {forIOThread: true}); | 172 {forIOThread: true}); |
176 }); | 173 }); |
177 }); | 174 }); |
178 | 175 |
179 })(); | 176 })(); |
OLD | NEW |