Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: chrome/renderer/resources/extensions/web_request_custom_bindings.js

Issue 9423049: Make registering custom hooks with schema_generated_bindings.js safer and (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698