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

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

Powered by Google App Engine
This is Rietveld 408576698