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

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

Issue 21297005: <webview>: Refactor Permission API to chrome (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cleanup_permissions
Patch Set: Fixed some bugs Created 7 years, 4 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) 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 // Shim that simulates a <webview> tag via Mutation Observers. 5 // Shim that simulates a <webview> tag via Mutation Observers.
6 // 6 //
7 // The actual tag is implemented via the browser plugin. The internals of this 7 // The actual tag is implemented via the browser plugin. The internals of this
8 // are hidden via Shadow DOM. 8 // are hidden via Shadow DOM.
9 9
10 var addTagWatcher = require('tagWatcher').addTagWatcher; 10 var addTagWatcher = require('tagWatcher').addTagWatcher;
(...skipping 18 matching lines...) Expand all
29 fields: [] 29 fields: []
30 }, 30 },
31 'consolemessage': { 31 'consolemessage': {
32 evt: createEvent('webview.onConsoleMessage'), 32 evt: createEvent('webview.onConsoleMessage'),
33 fields: ['level', 'message', 'line', 'sourceId'] 33 fields: ['level', 'message', 'line', 'sourceId']
34 }, 34 },
35 'contentload': { 35 'contentload': {
36 evt: createEvent('webview.onContentLoad'), 36 evt: createEvent('webview.onContentLoad'),
37 fields: [] 37 fields: []
38 }, 38 },
39 'dialog': {
lazyboy 2013/08/05 09:26:58 mixing this up with stable here seems a bit unclea
Fady Samuel 2013/08/06 07:14:40 Done.
40 cancelable: true,
41 customHandler: function(webview, event, webviewEvent) {
42 webview.maybeSetupExtDialogEvent_(event, webviewEvent);
43 },
44 evt: createEvent('webview.onDialog'),
45 fields: ['defaultPromptText', 'messageText', 'messageType', 'url']
46 },
39 'exit': { 47 'exit': {
40 evt: createEvent('webview.onExit'), 48 evt: createEvent('webview.onExit'),
41 fields: ['processId', 'reason'] 49 fields: ['processId', 'reason']
42 }, 50 },
43 'loadabort': { 51 'loadabort': {
44 evt: createEvent('webview.onLoadAbort'), 52 evt: createEvent('webview.onLoadAbort'),
45 fields: ['url', 'isTopLevel', 'reason'] 53 fields: ['url', 'isTopLevel', 'reason']
46 }, 54 },
47 'loadcommit': { 55 'loadcommit': {
48 customHandler: function(webview, event) { 56 customHandler: function(webview, event, webviewEvent) {
49 webview.currentEntryIndex_ = event.currentEntryIndex; 57 webview.currentEntryIndex_ = event.currentEntryIndex;
50 webview.entryCount_ = event.entryCount; 58 webview.entryCount_ = event.entryCount;
51 webview.processId_ = event.processId; 59 webview.processId_ = event.processId;
52 if (event.isTopLevel) { 60 if (event.isTopLevel) {
53 webview.browserPluginNode_.setAttribute('src', event.url); 61 webview.browserPluginNode_.setAttribute('src', event.url);
54 } 62 }
63 webview.webviewNode_.dispatchEvent(webviewEvent);
55 }, 64 },
56 evt: createEvent('webview.onLoadCommit'), 65 evt: createEvent('webview.onLoadCommit'),
57 fields: ['url', 'isTopLevel'] 66 fields: ['url', 'isTopLevel']
58 }, 67 },
59 'loadredirect': { 68 'loadredirect': {
60 evt: createEvent('webview.onLoadRedirect'), 69 evt: createEvent('webview.onLoadRedirect'),
61 fields: ['isTopLevel', 'oldUrl', 'newUrl'] 70 fields: ['isTopLevel', 'oldUrl', 'newUrl']
62 }, 71 },
63 'loadstart': { 72 'loadstart': {
64 evt: createEvent('webview.onLoadStart'), 73 evt: createEvent('webview.onLoadStart'),
65 fields: ['url', 'isTopLevel'] 74 fields: ['url', 'isTopLevel']
66 }, 75 },
67 'loadstop': { 76 'loadstop': {
68 evt: createEvent('webview.onLoadStop'), 77 evt: createEvent('webview.onLoadStop'),
69 fields: [] 78 fields: []
70 }, 79 },
80 'newwindow': {
81 cancelable: true,
82 customHandler: function(webview, event, webviewEvent) {
83 webview.setupExtNewWindowEvent_(event, webviewEvent);
84 },
85 evt: createEvent('webview.onNewWindow'),
86 fields: ['initialHeight', 'initialWidth', 'targetUrl',
lazyboy 2013/08/05 09:26:58 nit: here and below, since these don't fit in one
Fady Samuel 2013/08/06 07:14:40 Done.
87 'windowOpenDisposition', 'name']
88 },
89 'permissionrequest': {
90 cancelable: true,
91 customHandler: function(webview, event, webviewEvent) {
92 webview.setupExtPermissionEvent_(event, webviewEvent);
93 },
94 evt: createEvent('webview.onPermissionRequest'),
95 fields: ['lastUnlockedBySelf', 'permission', 'requestMethod', 'url',
96 'userGesture']
97 },
71 'responsive': { 98 'responsive': {
72 evt: createEvent('webview.onResponsive'), 99 evt: createEvent('webview.onResponsive'),
73 fields: ['processId'] 100 fields: ['processId']
74 }, 101 },
75 'unresponsive': { 102 'unresponsive': {
76 evt: createEvent('webview.onUnresponsive'), 103 evt: createEvent('webview.onUnresponsive'),
77 fields: ['processId'] 104 fields: ['processId']
78 } 105 }
79 }; 106 };
80 107
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 for (var eventName in WEB_VIEW_EXT_EVENTS) { 381 for (var eventName in WEB_VIEW_EXT_EVENTS) {
355 self.setupExtEvent_(eventName, WEB_VIEW_EXT_EVENTS[eventName]); 382 self.setupExtEvent_(eventName, WEB_VIEW_EXT_EVENTS[eventName]);
356 } 383 }
357 }; 384 };
358 this.browserPluginNode_.addEventListener('-internal-instanceid-allocated', 385 this.browserPluginNode_.addEventListener('-internal-instanceid-allocated',
359 onInstanceIdAllocated); 386 onInstanceIdAllocated);
360 387
361 for (var eventName in WEB_VIEW_EVENTS) { 388 for (var eventName in WEB_VIEW_EVENTS) {
362 this.setupEvent_(eventName, WEB_VIEW_EVENTS[eventName]); 389 this.setupEvent_(eventName, WEB_VIEW_EVENTS[eventName]);
363 } 390 }
364 this.setupNewWindowEvent_();
365 this.setupPermissionEvent_();
366 }; 391 };
367 392
368 /** 393 /**
369 * @private 394 * @private
370 */ 395 */
371 WebView.prototype.setupExtEvent_ = function(eventName, eventInfo) { 396 WebView.prototype.setupExtEvent_ = function(eventName, eventInfo) {
372 var self = this; 397 var self = this;
373 var webviewNode = this.webviewNode_; 398 var webviewNode = this.webviewNode_;
374 eventInfo.evt.addListener(function(event) { 399 eventInfo.evt.addListener(function(event) {
375 var webviewEvent = new Event(eventName, {bubbles: true}); 400 var details = {bubbles:true};
401 if (eventInfo.cancelable)
402 details.cancelable = true;
403 var webviewEvent = new Event(eventName, details);
376 $Array.forEach(eventInfo.fields, function(field) { 404 $Array.forEach(eventInfo.fields, function(field) {
377 webviewEvent[field] = event[field]; 405 if (event[field] != undefined) {
lazyboy 2013/08/05 09:26:58 use !== undefined
Fady Samuel 2013/08/06 07:14:40 Done.
406 webviewEvent[field] = event[field];
407 }
378 }); 408 });
379 if (eventInfo.customHandler) { 409 if (eventInfo.customHandler) {
380 eventInfo.customHandler(self, event); 410 eventInfo.customHandler(self, event, webviewEvent);
411 return;
381 } 412 }
382 webviewNode.dispatchEvent(webviewEvent); 413 webviewNode.dispatchEvent(webviewEvent);
383 }, {instanceId: self.instanceId_}); 414 }, {instanceId: self.instanceId_});
384 }; 415 };
385 416
386 /** 417 /**
387 * @private 418 * @private
388 */ 419 */
389 WebView.prototype.setupEvent_ = function(eventName, attribs) { 420 WebView.prototype.setupEvent_ = function(eventName, attribs) {
390 var webviewNode = this.webviewNode_; 421 var webviewNode = this.webviewNode_;
391 var internalname = '-internal-' + eventName; 422 var internalname = '-internal-' + eventName;
392 this.browserPluginNode_.addEventListener(internalname, function(e) { 423 this.browserPluginNode_.addEventListener(internalname, function(e) {
393 var evt = new Event(eventName, { bubbles: true }); 424 var evt = new Event(eventName, { bubbles: true });
394 var detail = e.detail ? JSON.parse(e.detail) : {}; 425 var detail = e.detail ? JSON.parse(e.detail) : {};
395 $Array.forEach(attribs, function(attribName) { 426 $Array.forEach(attribs, function(attribName) {
396 evt[attribName] = detail[attribName]; 427 evt[attribName] = detail[attribName];
397 }); 428 });
398 webviewNode.dispatchEvent(evt); 429 webviewNode.dispatchEvent(evt);
399 }); 430 });
400 }; 431 };
401 432
402 /** 433 /**
403 * @private 434 * @private
404 */ 435 */
405 WebView.prototype.setupNewWindowEvent_ = function() { 436 WebView.prototype.setupExtNewWindowEvent_ = function(event, webviewEvent) {
406 var ERROR_MSG_NEWWINDOW_ACTION_ALREADY_TAKEN = '<webview>: ' + 437 var ERROR_MSG_NEWWINDOW_ACTION_ALREADY_TAKEN = '<webview>: ' +
407 'An action has already been taken for this "newwindow" event.'; 438 'An action has already been taken for this "newwindow" event.';
408 439
409 var ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH = '<webview>: ' + 440 var ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH = '<webview>: ' +
410 'Unable to attach the new window to the provided webview.'; 441 'Unable to attach the new window to the provided webview.';
411 442
412 var ERROR_MSG_WEBVIEW_EXPECTED = '<webview> element expected.'; 443 var ERROR_MSG_WEBVIEW_EXPECTED = '<webview> element expected.';
413 444
414 var showWarningMessage = function() { 445 var showWarningMessage = function() {
415 var WARNING_MSG_NEWWINDOW_BLOCKED = '<webview>: A new window was blocked.'; 446 var WARNING_MSG_NEWWINDOW_BLOCKED = '<webview>: A new window was blocked.';
416 console.warn(WARNING_MSG_NEWWINDOW_BLOCKED); 447 console.warn(WARNING_MSG_NEWWINDOW_BLOCKED);
417 }; 448 };
418 449
419 var NEW_WINDOW_EVENT_ATTRIBUTES = [ 450 var self = this;
420 'initialHeight', 451 var browserPluginNode = this.browserPluginNode_;
421 'initialWidth', 452 var webviewNode = this.webviewNode_;
422 'targetUrl',
423 'windowOpenDisposition',
424 'name'
425 ];
426 453
427 var self = this; 454 var requestId = event.requestId;
428 var node = this.webviewNode_; 455 var actionTaken = false;
429 var browserPluginNode = this.browserPluginNode_;
430 456
431 var onTrackedObjectGone = function(requestId, e) { 457 var onTrackedObjectGone = function(requestId, e) {
432 var detail = e.detail ? JSON.parse(e.detail) : {}; 458 var detail = e.detail ? JSON.parse(e.detail) : {};
433 if (detail.id != requestId) { 459 if (detail.id != requestId) {
434 return; 460 return;
435 } 461 }
436 // If the request was pending then show a warning indiciating that a dialog
437 // was blocked.
438 if (browserPluginNode['-internal-setPermission'](requestId, false, '')) {
439 showWarningMessage();
440 }
441 };
442 462
443 browserPluginNode.addEventListener('-internal-newwindow', function(e) { 463 // Avoid showing a warning message if the decision has already been made.
444 var evt = new Event('newwindow', { bubbles: true, cancelable: true });
445 var detail = e.detail ? JSON.parse(e.detail) : {};
446
447 $Array.forEach(NEW_WINDOW_EVENT_ATTRIBUTES, function(attribName) {
448 evt[attribName] = detail[attribName];
449 });
450 var requestId = detail.requestId;
451 var actionTaken = false;
452
453 var validateCall = function () {
454 if (actionTaken) {
455 throw new Error(ERROR_MSG_NEWWINDOW_ACTION_ALREADY_TAKEN);
456 }
457 actionTaken = true;
458 };
459
460 var window = {
461 attach: function(webview) {
462 validateCall();
463 if (!webview)
464 throw new Error(ERROR_MSG_WEBVIEW_EXPECTED);
465 // Attach happens asynchronously to give the tagWatcher an opportunity
466 // to pick up the new webview before attach operates on it, if it hasn't
467 // been attached to the DOM already.
468 // Note: Any subsequent errors cannot be exceptions because they happen
469 // asynchronously.
470 setTimeout(function() {
471 var attached =
472 browserPluginNode['-internal-attachWindowTo'](webview,
473 detail.windowId);
474 if (!attached) {
475 console.error(ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH);
476 }
477 // If the object being passed into attach is not a valid <webview>
478 // then we will fail and it will be treated as if the new window
479 // was rejected. The permission API plumbing is used here to clean
480 // up the state created for the new window if attaching fails.
481 browserPluginNode['-internal-setPermission'](requestId, attached, '');
482 }, 0);
483 },
484 discard: function() {
485 validateCall();
486 browserPluginNode['-internal-setPermission'](requestId, false, '');
487 }
488 };
489 evt.window = window;
490
491 var defaultPrevented = !node.dispatchEvent(evt);
492 if (actionTaken) { 464 if (actionTaken) {
493 return; 465 return;
494 } 466 }
495 467
496 if (defaultPrevented) { 468 chrome.webview.setPermission(self.instanceId_, requestId, false, '');
497 // Make browser plugin track lifetime of |window|. 469 showWarningMessage();
498 var onTrackedObjectGoneWithRequestId = 470 };
499 $Function.bind(onTrackedObjectGone, self, requestId); 471
500 browserPluginNode.addEventListener('-internal-trackedobjectgone', 472
501 onTrackedObjectGoneWithRequestId); 473 var validateCall = function () {
502 browserPluginNode['-internal-trackObjectLifetime'](window, requestId); 474 if (actionTaken) {
503 } else { 475 throw new Error(ERROR_MSG_NEWWINDOW_ACTION_ALREADY_TAKEN);
504 actionTaken = true;
505 // The default action is to discard the window.
506 browserPluginNode['-internal-setPermission'](requestId, false, '');
507 showWarningMessage();
508 } 476 }
477 actionTaken = true;
478 };
509 479
510 }); 480 var window = {
481 attach: function(webview) {
482 validateCall();
483 if (!webview)
484 throw new Error(ERROR_MSG_WEBVIEW_EXPECTED);
485 // Attach happens asynchronously to give the tagWatcher an opportunity
486 // to pick up the new webview before attach operates on it, if it hasn't
487 // been attached to the DOM already.
488 // Note: Any subsequent errors cannot be exceptions because they happen
489 // asynchronously.
490 setTimeout(function() {
491 var attached =
492 browserPluginNode['-internal-attachWindowTo'](webview,
493 event.windowId);
494 if (!attached) {
495 console.error(ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH);
496 }
497 // If the object being passed into attach is not a valid <webview>
498 // then we will fail and it will be treated as if the new window
499 // was rejected. The permission API plumbing is used here to clean
500 // up the state created for the new window if attaching fails.
501 chrome.webview.setPermission(self.instanceId_, requestId, attached, '');
502 }, 0);
503 },
504 discard: function() {
505 validateCall();
506 chrome.webview.setPermission(self.instanceId_, requestId, false, '');
507 }
508 };
509 webviewEvent.window = window;
510
511 var defaultPrevented = !webviewNode.dispatchEvent(webviewEvent);
512 if (actionTaken) {
513 return;
514 }
515
516 if (defaultPrevented) {
517 // Make browser plugin track lifetime of |window|.
518 var onTrackedObjectGoneWithRequestId =
519 $Function.bind(onTrackedObjectGone, self, requestId);
520 browserPluginNode.addEventListener('-internal-trackedobjectgone',
521 onTrackedObjectGoneWithRequestId);
522 browserPluginNode['-internal-trackObjectLifetime'](window, requestId);
523 } else {
524 actionTaken = true;
525 // The default action is to discard the window.
526 chrome.webview.setPermission(self.instanceId_, requestId, false, '');
527 showWarningMessage();
528 }
511 }; 529 };
512 530
513 /** 531 /**
514 * @private 532 * @private
515 */ 533 */
516 WebView.prototype.setupExecuteCodeAPI_ = function() { 534 WebView.prototype.setupExecuteCodeAPI_ = function() {
517 var ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview>: ' + 535 var ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview>: ' +
518 'Script cannot be injected into content until the page has loaded.'; 536 'Script cannot be injected into content until the page has loaded.';
519 537
520 var self = this; 538 var self = this;
(...skipping 11 matching lines...) Expand all
532 } 550 }
533 this.webviewNode_['insertCSS'] = function(var_args) { 551 this.webviewNode_['insertCSS'] = function(var_args) {
534 validateCall(); 552 validateCall();
535 var args = $Array.concat([self.browserPluginNode_.getGuestInstanceId()], 553 var args = $Array.concat([self.browserPluginNode_.getGuestInstanceId()],
536 $Array.slice(arguments)); 554 $Array.slice(arguments));
537 $Function.apply(chrome.webview.insertCSS, null, args); 555 $Function.apply(chrome.webview.insertCSS, null, args);
538 } 556 }
539 }; 557 };
540 558
541 /** 559 /**
542 * @param {!Object} detail The event details, originated from <object>.
543 * @private 560 * @private
544 */ 561 */
545 WebView.prototype.setupPermissionEvent_ = function() { 562 WebView.prototype.getPermissionTypes_ = function() {
563 return ['media', 'geolocation', 'pointerLock', 'download'];
564 };
565
566 WebView.prototype.setupExtPermissionEvent_ = function(event, webviewEvent) {
546 var ERROR_MSG_PERMISSION_ALREADY_DECIDED = '<webview>: ' + 567 var ERROR_MSG_PERMISSION_ALREADY_DECIDED = '<webview>: ' +
547 'Permission has already been decided for this "permissionrequest" event.'; 568 'Permission has already been decided for this "permissionrequest" event.';
548 569
549 var showWarningMessage = function(permission) { 570 var showWarningMessage = function(permission) {
550 var WARNING_MSG_PERMISSION_DENIED = '<webview>: ' + 571 var WARNING_MSG_PERMISSION_DENIED = '<webview>: ' +
551 'The permission request for "%1" has been denied.'; 572 'The permission request for "%1" has been denied.';
552 console.warn(WARNING_MSG_PERMISSION_DENIED.replace('%1', permission)); 573 console.warn(WARNING_MSG_PERMISSION_DENIED.replace('%1', permission));
553 }; 574 };
554 575
555 var PERMISSION_TYPES = ['media', 'geolocation', 'pointerLock', 'download']; 576 var PERMISSION_TYPES = this.getPermissionTypes_();
556
557 var EXPOSED_PERMISSION_EVENT_ATTRIBS = [
558 'lastUnlockedBySelf',
559 'permission',
560 'requestMethod',
561 'url',
562 'userGesture'
563 ];
564 577
565 var self = this; 578 var self = this;
566 var node = this.webviewNode_;
567 var browserPluginNode = this.browserPluginNode_; 579 var browserPluginNode = this.browserPluginNode_;
568 var internalevent = '-internal-permissionrequest'; 580 var webviewNode = this.webviewNode_;
581
582 var requestId = event.requestId;
583 var decisionMade = false;
569 584
570 var onTrackedObjectGone = function(requestId, permission, e) { 585 var onTrackedObjectGone = function(requestId, permission, e) {
571 var detail = e.detail ? JSON.parse(e.detail) : {}; 586 var detail = e.detail ? JSON.parse(e.detail) : {};
572 if (detail.id != requestId) 587 if (detail.id != requestId) {
573 return;
574 // If the request was pending then show a warning indiciating that the
575 // permission was denied.
576 if (browserPluginNode['-internal-setPermission'](requestId, false, '')) {
577 showWarningMessage(permission);
578 }
579 };
580
581 browserPluginNode.addEventListener(internalevent, function(e) {
582 var evt = new Event('permissionrequest', {bubbles: true, cancelable: true});
583 var detail = e.detail ? JSON.parse(e.detail) : {};
584 $Array.forEach(EXPOSED_PERMISSION_EVENT_ATTRIBS, function(attribName) {
585 if (detail[attribName] !== undefined)
586 evt[attribName] = detail[attribName];
587 });
588 var requestId = detail.requestId;
589
590 if (detail.requestId == undefined ||
591 PERMISSION_TYPES.indexOf(detail.permission) < 0) {
592 return; 588 return;
593 } 589 }
594 590
595 // TODO(lazyboy): Also fill in evt.details (see webview specs). 591 // Avoid showing a warning message if the decision has already been made.
596 // http://crbug.com/141197.
597 var decisionMade = false;
598
599 var validateCall = function() {
600 if (decisionMade) {
601 throw new Error(ERROR_MSG_PERMISSION_ALREADY_DECIDED);
602 }
603 decisionMade = true;
604 };
605
606 // Construct the event.request object.
607 var request = {
608 allow: function() {
609 validateCall();
610 browserPluginNode['-internal-setPermission'](requestId, true, '');
611 },
612 deny: function() {
613 validateCall();
614 browserPluginNode['-internal-setPermission'](requestId, false, '');
615 }
616 };
617 evt.request = request;
618
619 var defaultPrevented = !node.dispatchEvent(evt);
620 if (decisionMade) { 592 if (decisionMade) {
621 return; 593 return;
622 } 594 }
623 595
624 if (defaultPrevented) { 596 chrome.webview.setPermission(self.instanceId_, requestId, false, '');
625 // Make browser plugin track lifetime of |request|. 597 showWarningMessage(permission);
626 var onTrackedObjectGoneWithRequestId = 598 };
627 $Function.bind( 599
628 onTrackedObjectGone, self, requestId, detail.permission); 600 var validateCall = function() {
629 browserPluginNode.addEventListener('-internal-trackedobjectgone', 601 if (decisionMade) {
630 onTrackedObjectGoneWithRequestId); 602 throw new Error(ERROR_MSG_PERMISSION_ALREADY_DECIDED);
631 browserPluginNode['-internal-trackObjectLifetime'](request, requestId);
632 } else {
633 decisionMade = true;
634 browserPluginNode['-internal-setPermission'](requestId, false, '');
635 showWarningMessage(detail.permission);
636 } 603 }
637 }); 604 decisionMade = true;
605 };
606
607 // Construct the event.request object.
608 var request = {
609 allow: function() {
610 validateCall();
611 chrome.webview.setPermission(self.instanceId_, requestId, true, '');
612 },
613 deny: function() {
614 validateCall();
615 chrome.webview.setPermission(self.instanceId_, requestId, false, '');
616 }
617 };
618 webviewEvent.request = request;
619
620 var defaultPrevented = !webviewNode.dispatchEvent(webviewEvent);
621 if (decisionMade) {
622 return;
623 }
624
625 if (defaultPrevented) {
626 // Make browser plugin track lifetime of |request|.
627 var onTrackedObjectGoneWithRequestId =
628 $Function.bind(
629 onTrackedObjectGone, self, requestId, event.permission);
630 browserPluginNode.addEventListener('-internal-trackedobjectgone',
631 onTrackedObjectGoneWithRequestId);
632 browserPluginNode['-internal-trackObjectLifetime'](request, requestId);
633 } else {
634 decisionMade = true;
635 chrome.webview.setPermission(self.instanceId_, requestId, false, '');
636 showWarningMessage(event.permission);
637 }
638 }; 638 };
639 639
640 /** 640 /**
641 * Implemented when the experimental API is available. 641 * Implemented when the experimental API is available.
642 * @private 642 * @private
643 */ 643 */
644 WebView.prototype.maybeSetupExperimentalAPI_ = function() {}; 644 WebView.prototype.maybeSetupExperimentalAPI_ = function() {};
645 645
646 /**
647 * Implemented when the experimental API is available.
648 * @private
649 */
650 WebView.prototype.maybeSetupExtDialogEvent_ = function() {};
651
646 exports.WebView = WebView; 652 exports.WebView = WebView;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698