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

Side by Side Diff: extensions/renderer/resources/guest_view/guest_view.js

Issue 1165773004: Extract the element implementation logic to function mods in <webview>. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@qui
Patch Set: fix comments Created 5 years, 6 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 // This module implements a wrapper for a guestview that manages its 5 // This module implements a wrapper for a guestview that manages its
6 // creation, attaching, and destruction. 6 // creation, attaching, and destruction.
7 7
8 var CreateEvent = require('guestViewEvents').CreateEvent; 8 var CreateEvent = require('guestViewEvents').CreateEvent;
9 var EventBindings = require('event_bindings'); 9 var EventBindings = require('event_bindings');
10 var GuestViewInternal = 10 var GuestViewInternal =
11 require('binding').Binding.create('guestViewInternal').generate(); 11 require('binding').Binding.create('guestViewInternal').generate();
12 var GuestViewInternalNatives = requireNative('guest_view_internal'); 12 var GuestViewInternalNatives = requireNative('guest_view_internal');
13 13
14 // Events. 14 // Events.
15 var ResizeEvent = CreateEvent('guestViewInternal.onResize'); 15 var ResizeEvent = CreateEvent('guestViewInternal.onResize');
16 16
17 // Possible states.
18 var GUEST_STATE_ATTACHED = 2;
19 var GUEST_STATE_CREATED = 1;
20 var GUEST_STATE_START = 0;
21
22 // Error messages. 17 // Error messages.
23 var ERROR_MSG_ALREADY_ATTACHED = 'The guest has already been attached.'; 18 var ERROR_MSG_ALREADY_ATTACHED = 'The guest has already been attached.';
24 var ERROR_MSG_ALREADY_CREATED = 'The guest has already been created.'; 19 var ERROR_MSG_ALREADY_CREATED = 'The guest has already been created.';
25 var ERROR_MSG_INVALID_STATE = 'The guest is in an invalid state.'; 20 var ERROR_MSG_INVALID_STATE = 'The guest is in an invalid state.';
26 var ERROR_MSG_NOT_ATTACHED = 'The guest is not attached.'; 21 var ERROR_MSG_NOT_ATTACHED = 'The guest is not attached.';
27 var ERROR_MSG_NOT_CREATED = 'The guest has not been created.'; 22 var ERROR_MSG_NOT_CREATED = 'The guest has not been created.';
28 23
29 // Properties. 24 // Properties.
30 var PROPERTY_ON_RESIZE = 'onresize'; 25 var PROPERTY_ON_RESIZE = 'onresize';
31 26
32 // Contains and hides the internal implementation details of |GuestView|, 27 // Contains and hides the internal implementation details of |GuestView|,
33 // including maintaining its state and enforcing the proper usage of its API 28 // including maintaining its state and enforcing the proper usage of its API
34 // fucntions. 29 // fucntions.
35 function GuestViewImpl(guestView, viewType, guestInstanceId) { 30 function GuestViewImpl(guestView, viewType, guestInstanceId) {
36 if (guestInstanceId) { 31 if (guestInstanceId) {
37 this.id = guestInstanceId; 32 this.id = guestInstanceId;
38 this.state = GUEST_STATE_CREATED; 33 this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
39 } else { 34 } else {
40 this.id = 0; 35 this.id = 0;
41 this.state = GUEST_STATE_START; 36 this.state = GuestViewImpl.GuestState.GUEST_STATE_START;
42 } 37 }
43 this.actionQueue = []; 38 this.actionQueue = [];
44 this.contentWindow = null; 39 this.contentWindow = null;
45 this.guestView = guestView; 40 this.guestView = guestView;
46 this.pendingAction = null; 41 this.pendingAction = null;
47 this.viewType = viewType; 42 this.viewType = viewType;
48 this.internalInstanceId = 0; 43 this.internalInstanceId = 0;
49 44
50 this.setupOnResize(); 45 this.setupOnResize();
51 } 46 }
52 47
48 // Possible states.
49 GuestViewImpl.GuestState = {
50 GUEST_STATE_START: 0,
51 GUEST_STATE_CREATED: 1,
52 GUEST_STATE_ATTACHED: 2
53 };
54
53 // Sets up the onResize property on the GuestView. 55 // Sets up the onResize property on the GuestView.
54 GuestViewImpl.prototype.setupOnResize = function() { 56 GuestViewImpl.prototype.setupOnResize = function() {
55 $Object.defineProperty(this.guestView, PROPERTY_ON_RESIZE, { 57 $Object.defineProperty(this.guestView, PROPERTY_ON_RESIZE, {
56 get: function() { 58 get: function() {
57 return this[PROPERTY_ON_RESIZE]; 59 return this[PROPERTY_ON_RESIZE];
58 }.bind(this), 60 }.bind(this),
59 set: function(value) { 61 set: function(value) {
60 this[PROPERTY_ON_RESIZE] = value; 62 this[PROPERTY_ON_RESIZE] = value;
61 }.bind(this), 63 }.bind(this),
62 enumerable: true 64 enumerable: true
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 var view = GuestViewInternalNatives.GetViewFromID(viewInstanceId); 140 var view = GuestViewInternalNatives.GetViewFromID(viewInstanceId);
139 if (view && view.guest) { 141 if (view && view.guest) {
140 return $Function.apply(func, 142 return $Function.apply(func,
141 privates(view.guest).internal, 143 privates(view.guest).internal,
142 $Array.slice(arguments)); 144 $Array.slice(arguments));
143 } 145 }
144 }; 146 };
145 }; 147 };
146 148
147 // Internal implementation of attach(). 149 // Internal implementation of attach().
148 GuestViewImpl.prototype.attachImpl = function( 150 GuestViewImpl.prototype.attachImpl$ = function(
149 internalInstanceId, viewInstanceId, attachParams, callback) { 151 internalInstanceId, viewInstanceId, attachParams, callback) {
150 // Check the current state. 152 // Check the current state.
151 if (!this.checkState('attach')) { 153 if (!this.checkState('attach')) {
152 this.handleCallback(callback); 154 this.handleCallback(callback);
153 return; 155 return;
154 } 156 }
155 157
156 // Callback wrapper function to store the contentWindow from the attachGuest() 158 // Callback wrapper function to store the contentWindow from the attachGuest()
157 // callback, handle potential attaching failure, register an automatic detach, 159 // callback, handle potential attaching failure, register an automatic detach,
158 // and advance the queue. 160 // and advance the queue.
159 var callbackWrapper = function(callback, contentWindow) { 161 var callbackWrapper = function(callback, contentWindow) {
160 // Check if attaching failed. 162 // Check if attaching failed.
161 if (!contentWindow) { 163 if (!contentWindow) {
162 this.state = GUEST_STATE_CREATED; 164 this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
163 this.internalInstanceId = 0; 165 this.internalInstanceId = 0;
164 } else { 166 } else {
165 // Only update the contentWindow if attaching is successful. 167 // Only update the contentWindow if attaching is successful.
166 this.contentWindow = contentWindow; 168 this.contentWindow = contentWindow;
167 } 169 }
168 170
169 this.handleCallback(callback); 171 this.handleCallback(callback);
170 }; 172 };
171 173
172 attachParams['instanceId'] = viewInstanceId; 174 attachParams['instanceId'] = viewInstanceId;
173 GuestViewInternalNatives.AttachGuest(internalInstanceId, 175 GuestViewInternalNatives.AttachGuest(internalInstanceId,
174 this.id, 176 this.id,
175 attachParams, 177 attachParams,
176 callbackWrapper.bind(this, callback)); 178 callbackWrapper.bind(this, callback));
177 179
178 this.internalInstanceId = internalInstanceId; 180 this.internalInstanceId = internalInstanceId;
179 this.state = GUEST_STATE_ATTACHED; 181 this.state = GuestViewImpl.GuestState.GUEST_STATE_ATTACHED;
180 182
181 // Detach automatically when the container is destroyed. 183 // Detach automatically when the container is destroyed.
182 GuestViewInternalNatives.RegisterDestructionCallback( 184 GuestViewInternalNatives.RegisterDestructionCallback(
183 internalInstanceId, this.weakWrapper(function() { 185 internalInstanceId, this.weakWrapper(function() {
184 if (this.state != GUEST_STATE_ATTACHED || 186 if (this.state != GuestViewImpl.GuestState.GUEST_STATE_ATTACHED ||
185 this.internalInstanceId != internalInstanceId) { 187 this.internalInstanceId != internalInstanceId) {
186 return; 188 return;
187 } 189 }
188 190
189 this.internalInstanceId = 0; 191 this.internalInstanceId = 0;
190 this.state = GUEST_STATE_CREATED; 192 this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
191 }, viewInstanceId)); 193 }, viewInstanceId));
192 }; 194 };
193 195
194 // Internal implementation of create(). 196 // Internal implementation of create().
195 GuestViewImpl.prototype.createImpl = function(createParams, callback) { 197 GuestViewImpl.prototype.createImpl$ = function(createParams, callback) {
196 // Check the current state. 198 // Check the current state.
197 if (!this.checkState('create')) { 199 if (!this.checkState('create')) {
198 this.handleCallback(callback); 200 this.handleCallback(callback);
199 return; 201 return;
200 } 202 }
201 203
202 // Callback wrapper function to store the guestInstanceId from the 204 // Callback wrapper function to store the guestInstanceId from the
203 // createGuest() callback, handle potential creation failure, and advance the 205 // createGuest() callback, handle potential creation failure, and advance the
204 // queue. 206 // queue.
205 var callbackWrapper = function(callback, guestInfo) { 207 var callbackWrapper = function(callback, guestInfo) {
206 this.id = guestInfo.id; 208 this.id = guestInfo.id;
207 this.contentWindow = 209 this.contentWindow =
208 GuestViewInternalNatives.GetContentWindow(guestInfo.contentWindowId); 210 GuestViewInternalNatives.GetContentWindow(guestInfo.contentWindowId);
209 211
210 // Check if creation failed. 212 // Check if creation failed.
211 if (this.id === 0) { 213 if (this.id === 0) {
212 this.state = GUEST_STATE_START; 214 this.state = GuestViewImpl.GuestState.GUEST_STATE_START;
213 this.contentWindow = null; 215 this.contentWindow = null;
214 } 216 }
215 217
216 ResizeEvent.addListener(this.callOnResize, {instanceId: this.id}); 218 ResizeEvent.addListener(this.callOnResize, {instanceId: this.id});
217 this.handleCallback(callback); 219 this.handleCallback(callback);
218 }; 220 };
219 221
220 GuestViewInternal.createGuest(this.viewType, 222 this.sendCreateRequest(createParams, callbackWrapper.bind(this, callback));
221 createParams,
222 callbackWrapper.bind(this, callback));
223 223
224 this.state = GUEST_STATE_CREATED; 224 this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
225 };
226
227 GuestViewImpl.prototype.sendCreateRequest = function(
228 createParams, boundCallback) {
229 GuestViewInternal.createGuest(this.viewType, createParams, boundCallback);
225 }; 230 };
226 231
227 // Internal implementation of destroy(). 232 // Internal implementation of destroy().
228 GuestViewImpl.prototype.destroyImpl = function(callback) { 233 GuestViewImpl.prototype.destroyImpl = function(callback) {
229 // Check the current state. 234 // Check the current state.
230 if (!this.checkState('destroy')) { 235 if (!this.checkState('destroy')) {
231 this.handleCallback(callback); 236 this.handleCallback(callback);
232 return; 237 return;
233 } 238 }
234 239
235 if (this.state == GUEST_STATE_START) { 240 if (this.state == GuestViewImpl.GuestState.GUEST_STATE_START) {
236 // destroy() does nothing in this case. 241 // destroy() does nothing in this case.
237 this.handleCallback(callback); 242 this.handleCallback(callback);
238 return; 243 return;
239 } 244 }
240 245
241 // If this guest is attached, then detach it first. 246 // If this guest is attached, then detach it first.
242 if (!!this.internalInstanceId) { 247 if (!!this.internalInstanceId) {
243 GuestViewInternalNatives.DetachGuest(this.internalInstanceId); 248 GuestViewInternalNatives.DetachGuest(this.internalInstanceId);
244 } 249 }
245 250
246 GuestViewInternal.destroyGuest(this.id, 251 GuestViewInternal.destroyGuest(this.id,
247 this.handleCallback.bind(this, callback)); 252 this.handleCallback.bind(this, callback));
248 253
249 // Reset the state of the destroyed guest; 254 // Reset the state of the destroyed guest;
250 this.contentWindow = null; 255 this.contentWindow = null;
251 this.id = 0; 256 this.id = 0;
252 this.internalInstanceId = 0; 257 this.internalInstanceId = 0;
253 this.state = GUEST_STATE_START; 258 this.state = GuestViewImpl.GuestState.GUEST_STATE_START;
254 if (ResizeEvent.hasListener(this.callOnResize)) { 259 if (ResizeEvent.hasListener(this.callOnResize)) {
255 ResizeEvent.removeListener(this.callOnResize); 260 ResizeEvent.removeListener(this.callOnResize);
256 } 261 }
257 }; 262 };
258 263
259 // Internal implementation of detach(). 264 // Internal implementation of detach().
260 GuestViewImpl.prototype.detachImpl = function(callback) { 265 GuestViewImpl.prototype.detachImpl = function(callback) {
261 // Check the current state. 266 // Check the current state.
262 if (!this.checkState('detach')) { 267 if (!this.checkState('detach')) {
263 this.handleCallback(callback); 268 this.handleCallback(callback);
264 return; 269 return;
265 } 270 }
266 271
267 GuestViewInternalNatives.DetachGuest( 272 GuestViewInternalNatives.DetachGuest(
268 this.internalInstanceId, 273 this.internalInstanceId,
269 this.handleCallback.bind(this, callback)); 274 this.handleCallback.bind(this, callback));
270 275
271 this.internalInstanceId = 0; 276 this.internalInstanceId = 0;
272 this.state = GUEST_STATE_CREATED; 277 this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
273 }; 278 };
274 279
275 // Internal implementation of setSize(). 280 // Internal implementation of setSize().
276 GuestViewImpl.prototype.setSizeImpl = function(sizeParams, callback) { 281 GuestViewImpl.prototype.setSizeImpl = function(sizeParams, callback) {
277 // Check the current state. 282 // Check the current state.
278 if (!this.checkState('setSize')) { 283 if (!this.checkState('setSize')) {
279 this.handleCallback(callback); 284 this.handleCallback(callback);
280 return; 285 return;
281 } 286 }
282 287
283 GuestViewInternal.setSize(this.id, sizeParams, 288 GuestViewInternal.setSize(this.id, sizeParams,
284 this.handleCallback.bind(this, callback)); 289 this.handleCallback.bind(this, callback));
285 }; 290 };
286 291
287 // The exposed interface to a guestview. Exposes in its API the functions 292 // The exposed interface to a guestview. Exposes in its API the functions
288 // attach(), create(), destroy(), and getId(). All other implementation details 293 // attach(), create(), destroy(), and getId(). All other implementation details
289 // are hidden. 294 // are hidden.
290 function GuestView(viewType, guestInstanceId) { 295 function GuestView(viewType, guestInstanceId) {
291 privates(this).internal = new GuestViewImpl(this, viewType, guestInstanceId); 296 privates(this).internal = new GuestViewImpl(this, viewType, guestInstanceId);
292 } 297 }
293 298
294 // Attaches the guestview to the container with ID |internalInstanceId|. 299 // Attaches the guestview to the container with ID |internalInstanceId|.
295 GuestView.prototype.attach = function( 300 GuestView.prototype.attach = function(
296 internalInstanceId, viewInstanceId, attachParams, callback) { 301 internalInstanceId, viewInstanceId, attachParams, callback) {
297 var internal = privates(this).internal; 302 var internal = privates(this).internal;
298 internal.actionQueue.push(internal.attachImpl.bind( 303 internal.actionQueue.push(internal.attachImpl$.bind(
299 internal, internalInstanceId, viewInstanceId, attachParams, callback)); 304 internal, internalInstanceId, viewInstanceId, attachParams, callback));
300 internal.performNextAction(); 305 internal.performNextAction();
301 }; 306 };
302 307
303 // Creates the guestview. 308 // Creates the guestview.
304 GuestView.prototype.create = function(createParams, callback) { 309 GuestView.prototype.create = function(createParams, callback) {
305 var internal = privates(this).internal; 310 var internal = privates(this).internal;
306 internal.actionQueue.push(internal.createImpl.bind( 311 internal.actionQueue.push(internal.createImpl$.bind(
307 internal, createParams, callback)); 312 internal, createParams, callback));
308 internal.performNextAction(); 313 internal.performNextAction();
309 }; 314 };
310 315
311 // Destroys the guestview. Nothing can be done with the guestview after it has 316 // Destroys the guestview. Nothing can be done with the guestview after it has
312 // been destroyed. 317 // been destroyed.
313 GuestView.prototype.destroy = function(callback) { 318 GuestView.prototype.destroy = function(callback) {
314 var internal = privates(this).internal; 319 var internal = privates(this).internal;
315 internal.actionQueue.push(internal.destroyImpl.bind(internal, callback)); 320 internal.actionQueue.push(internal.destroyImpl.bind(internal, callback));
316 internal.performNextAction(); 321 internal.performNextAction();
(...skipping 22 matching lines...) Expand all
339 }; 344 };
340 345
341 // Returns the ID for this guestview. 346 // Returns the ID for this guestview.
342 GuestView.prototype.getId = function() { 347 GuestView.prototype.getId = function() {
343 var internal = privates(this).internal; 348 var internal = privates(this).internal;
344 return internal.id; 349 return internal.id;
345 }; 350 };
346 351
347 // Exports 352 // Exports
348 exports.GuestView = GuestView; 353 exports.GuestView = GuestView;
354 exports.GuestViewImpl = GuestViewImpl;
355 exports.ResizeEvent = ResizeEvent;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698