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

Side by Side Diff: chrome/renderer/resources/event_bindings.js

Issue 147033: Refactor extension bindings to share code, avoid exposing hidden variables (Closed)
Patch Set: at head Created 11 years, 5 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 // ----------------------------------------------------------------------------- 5 // -----------------------------------------------------------------------------
6 // NOTE: If you change this file you need to touch renderer_resources.grd to 6 // NOTE: If you change this file you need to touch renderer_resources.grd to
7 // have your change take effect. 7 // have your change take effect.
8 // ----------------------------------------------------------------------------- 8 // -----------------------------------------------------------------------------
9 9
10 var chrome = chrome || {}; 10 var chrome = chrome || {};
11 (function () { 11 (function () {
12 native function GetChromeHidden();
12 native function AttachEvent(eventName); 13 native function AttachEvent(eventName);
13 native function DetachEvent(eventName); 14 native function DetachEvent(eventName);
15 native function GetNextRequestId();
16
17 var chromeHidden = GetChromeHidden();
14 18
15 // Event object. If opt_eventName is provided, this object represents 19 // Event object. If opt_eventName is provided, this object represents
16 // the unique instance of that named event, and dispatching an event 20 // the unique instance of that named event, and dispatching an event
17 // with that name will route through this object's listeners. 21 // with that name will route through this object's listeners.
18 // 22 //
19 // Example: 23 // Example:
20 // chrome.tabs.onChanged = new chrome.Event("tab-changed"); 24 // chrome.tabs.onChanged = new chrome.Event("tab-changed");
21 // chrome.tabs.onChanged.addListener(function(data) { alert(data); }); 25 // chrome.tabs.onChanged.addListener(function(data) { alert(data); });
22 // chrome.Event.dispatch_("tab-changed", "hi"); 26 // chromeHidden.Event.dispatch("tab-changed", "hi");
23 // will result in an alert dialog that says 'hi'. 27 // will result in an alert dialog that says 'hi'.
24 chrome.Event = function(opt_eventName) { 28 chrome.Event = function(opt_eventName) {
25 this.eventName_ = opt_eventName; 29 this.eventName_ = opt_eventName;
26 this.listeners_ = []; 30 this.listeners_ = [];
27 }; 31 };
28 32
29 // A map of event names to the event object that is registered to that name. 33 // A map of event names to the event object that is registered to that name.
30 chrome.Event.attached_ = {}; 34 var attachedNamedEvents = {};
35
36 // An array of all attached event objects, used for detaching on unload.
37 var allAttachedEvents = [];
38
39 chromeHidden.Event = {};
31 40
32 // Dispatches a named event with the given JSON array, which is deserialized 41 // Dispatches a named event with the given JSON array, which is deserialized
33 // before dispatch. The JSON array is the list of arguments that will be 42 // before dispatch. The JSON array is the list of arguments that will be
34 // sent with the event callback. 43 // sent with the event callback.
35 chrome.Event.dispatchJSON_ = function(name, args) { 44 chromeHidden.Event.dispatchJSON = function(name, args) {
36 if (chrome.Event.attached_[name]) { 45 if (attachedNamedEvents[name]) {
37 if (args) { 46 if (args) {
38 args = JSON.parse(args); 47 args = JSON.parse(args);
39 } 48 }
40 chrome.Event.attached_[name].dispatch.apply( 49 attachedNamedEvents[name].dispatch.apply(
41 chrome.Event.attached_[name], args); 50 attachedNamedEvents[name], args);
42 } 51 }
43 }; 52 };
44 53
45 // Dispatches a named event with the given arguments, supplied as an array. 54 // Dispatches a named event with the given arguments, supplied as an array.
46 chrome.Event.dispatch_ = function(name, args) { 55 chromeHidden.Event.dispatch = function(name, args) {
47 if (chrome.Event.attached_[name]) { 56 if (attachedNamedEvents[name]) {
48 chrome.Event.attached_[name].dispatch.apply( 57 attachedNamedEvents[name].dispatch.apply(
49 chrome.Event.attached_[name], args); 58 attachedNamedEvents[name], args);
50 } 59 }
51 }; 60 };
52 61
53 // Registers a callback to be called when this event is dispatched. 62 // Registers a callback to be called when this event is dispatched.
54 chrome.Event.prototype.addListener = function(cb) { 63 chrome.Event.prototype.addListener = function(cb) {
55 this.listeners_.push(cb); 64 this.listeners_.push(cb);
56 if (this.listeners_.length == 1) { 65 if (this.listeners_.length == 1) {
57 this.attach_(); 66 this.attach_();
58 } 67 }
59 }; 68 };
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 } catch (e) { 107 } catch (e) {
99 console.error(e); 108 console.error(e);
100 } 109 }
101 } 110 }
102 }; 111 };
103 112
104 // Attaches this event object to its name. Only one object can have a given 113 // Attaches this event object to its name. Only one object can have a given
105 // name. 114 // name.
106 chrome.Event.prototype.attach_ = function() { 115 chrome.Event.prototype.attach_ = function() {
107 AttachEvent(this.eventName_); 116 AttachEvent(this.eventName_);
108 this.unloadHandler_ = this.detach_.bind(this); 117 allAttachedEvents[allAttachedEvents.length] = this;
109 window.addEventListener('unload', this.unloadHandler_, false);
110 if (!this.eventName_) 118 if (!this.eventName_)
111 return; 119 return;
112 120
113 if (chrome.Event.attached_[this.eventName_]) { 121 if (attachedNamedEvents[this.eventName_]) {
114 throw new Error("chrome.Event '" + this.eventName_ + 122 throw new Error("chrome.Event '" + this.eventName_ +
115 "' is already attached."); 123 "' is already attached.");
116 } 124 }
117 125
118 chrome.Event.attached_[this.eventName_] = this; 126 attachedNamedEvents[this.eventName_] = this;
119 }; 127 };
120 128
121 // Detaches this event object from its name. 129 // Detaches this event object from its name.
122 chrome.Event.prototype.detach_ = function() { 130 chrome.Event.prototype.detach_ = function() {
123 window.removeEventListener('unload', this.unloadHandler_, false); 131 var i = allAttachedEvents.indexOf(this);
132 if (i >= 0)
133 delete allAttachedEvents[i];
124 DetachEvent(this.eventName_); 134 DetachEvent(this.eventName_);
125 if (!this.eventName_) 135 if (!this.eventName_)
126 return; 136 return;
127 137
128 if (!chrome.Event.attached_[this.eventName_]) { 138 if (!attachedNamedEvents[this.eventName_]) {
129 throw new Error("chrome.Event '" + this.eventName_ + 139 throw new Error("chrome.Event '" + this.eventName_ +
130 "' is not attached."); 140 "' is not attached.");
131 } 141 }
132 142
133 delete chrome.Event.attached_[this.eventName_]; 143 delete attachedNamedEvents[this.eventName_];
134 }; 144 };
145
146 // Callback handling.
147 var callbacks = [];
148 chromeHidden.handleResponse = function(requestId, name,
149 success, response, error) {
150 try {
151 if (!success) {
152 if (!error)
153 error = "Unknown error."
154 console.error("Error during " + name + ": " + error);
155 return;
156 }
157
158 if (callbacks[requestId]) {
159 if (response) {
160 callbacks[requestId](JSON.parse(response));
161 } else {
162 callbacks[requestId]();
163 }
164 }
165 } finally {
166 delete callbacks[requestId];
167 }
168 };
169
170 // Send an API request and optionally register a callback.
171 chromeHidden.sendRequest = function(request, args, callback) {
172 // JSON.stringify doesn't support a root object which is undefined.
173 if (args === undefined)
174 args = null;
175 var sargs = JSON.stringify(args);
176 var requestId = GetNextRequestId();
177 var hasCallback = false;
178 if (callback) {
179 hasCallback = true;
180 callbacks[requestId] = callback;
181 }
182 request(sargs, requestId, hasCallback);
183 }
184
185 // Special unload event: we don't use the DOM unload because that slows
186 // down tab shutdown. On the other hand, this might not always fire, since
187 // Chrome will terminate renderers on shutdown (SuddenTermination).
188 chromeHidden.onUnload = new chrome.Event();
189
190 chromeHidden.dispatchOnUnload = function() {
191 chromeHidden.onUnload.dispatch();
192 for (var i in allAttachedEvents)
193 allAttachedEvents[i].detach_();
194 }
135 })(); 195 })();
OLDNEW
« no previous file with comments | « chrome/renderer/renderer_resources.grd ('k') | chrome/renderer/resources/extension_process_bindings.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698