OLD | NEW |
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 // This module implements Webview (<webview>) as a custom element that wraps a | 5 // This module implements Webview (<webview>) as a custom element that wraps a |
6 // BrowserPlugin object element. The object element is hidden within | 6 // BrowserPlugin object element. The object element is hidden within |
7 // the shadow DOM of the Webview element. | 7 // the shadow DOM of the Webview element. |
8 | 8 |
9 var DocumentNatives = requireNative('document_natives'); | 9 var DocumentNatives = requireNative('document_natives'); |
10 var EventBindings = require('event_bindings'); | 10 var EventBindings = require('event_bindings'); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 fields: [] | 59 fields: [] |
60 }, | 60 }, |
61 'consolemessage': { | 61 'consolemessage': { |
62 evt: CreateEvent('webview.onConsoleMessage'), | 62 evt: CreateEvent('webview.onConsoleMessage'), |
63 fields: ['level', 'message', 'line', 'sourceId'] | 63 fields: ['level', 'message', 'line', 'sourceId'] |
64 }, | 64 }, |
65 'contentload': { | 65 'contentload': { |
66 evt: CreateEvent('webview.onContentLoad'), | 66 evt: CreateEvent('webview.onContentLoad'), |
67 fields: [] | 67 fields: [] |
68 }, | 68 }, |
| 69 'dialog': { |
| 70 cancelable: true, |
| 71 customHandler: function(webViewInternal, event, webViewEvent) { |
| 72 webViewInternal.handleDialogEvent(event, webViewEvent); |
| 73 }, |
| 74 evt: CreateEvent('webview.onDialog'), |
| 75 fields: ['defaultPromptText', 'messageText', 'messageType', 'url'] |
| 76 }, |
69 'exit': { | 77 'exit': { |
70 evt: CreateEvent('webview.onExit'), | 78 evt: CreateEvent('webview.onExit'), |
71 fields: ['processId', 'reason'] | 79 fields: ['processId', 'reason'] |
72 }, | 80 }, |
73 'loadabort': { | 81 'loadabort': { |
74 cancelable: true, | 82 cancelable: true, |
75 customHandler: function(webViewInternal, event, webViewEvent) { | 83 customHandler: function(webViewInternal, event, webViewEvent) { |
76 webViewInternal.handleLoadAbortEvent(event, webViewEvent); | 84 webViewInternal.handleLoadAbortEvent(event, webViewEvent); |
77 }, | 85 }, |
78 evt: CreateEvent('webview.onLoadAbort'), | 86 evt: CreateEvent('webview.onLoadAbort'), |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 */ | 636 */ |
629 WebViewInternal.prototype.getPermissionTypes = function() { | 637 WebViewInternal.prototype.getPermissionTypes = function() { |
630 var permissions = | 638 var permissions = |
631 ['media', 'geolocation', 'pointerLock', 'download', 'loadplugin']; | 639 ['media', 'geolocation', 'pointerLock', 'download', 'loadplugin']; |
632 return permissions.concat(this.maybeGetExperimentalPermissions()); | 640 return permissions.concat(this.maybeGetExperimentalPermissions()); |
633 }; | 641 }; |
634 | 642 |
635 /** | 643 /** |
636 * @private | 644 * @private |
637 */ | 645 */ |
| 646 WebViewInternal.prototype.handleDialogEvent = |
| 647 function(event, webViewEvent) { |
| 648 var showWarningMessage = function(dialogType) { |
| 649 var VOWELS = ['a', 'e', 'i', 'o', 'u']; |
| 650 var WARNING_MSG_DIALOG_BLOCKED = '<webview>: %1 %2 dialog was blocked.'; |
| 651 var article = (VOWELS.indexOf(dialogType.charAt(0)) >= 0) ? 'An' : 'A'; |
| 652 var output = WARNING_MSG_DIALOG_BLOCKED.replace('%1', article); |
| 653 output = output.replace('%2', dialogType); |
| 654 window.console.warn(output); |
| 655 }; |
| 656 |
| 657 var self = this; |
| 658 var browserPluginNode = this.browserPluginNode; |
| 659 var webviewNode = this.webviewNode; |
| 660 |
| 661 var requestId = event.requestId; |
| 662 var actionTaken = false; |
| 663 |
| 664 var validateCall = function() { |
| 665 var ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN = '<webview>: ' + |
| 666 'An action has already been taken for this "dialog" event.'; |
| 667 |
| 668 if (actionTaken) { |
| 669 throw new Error(ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN); |
| 670 } |
| 671 actionTaken = true; |
| 672 }; |
| 673 |
| 674 var dialog = { |
| 675 ok: function(user_input) { |
| 676 validateCall(); |
| 677 user_input = user_input || ''; |
| 678 WebView.setPermission(self.instanceId, requestId, 'allow', user_input); |
| 679 }, |
| 680 cancel: function() { |
| 681 validateCall(); |
| 682 WebView.setPermission(self.instanceId, requestId, 'deny'); |
| 683 } |
| 684 }; |
| 685 webViewEvent.dialog = dialog; |
| 686 |
| 687 var defaultPrevented = !webviewNode.dispatchEvent(webViewEvent); |
| 688 if (actionTaken) { |
| 689 return; |
| 690 } |
| 691 |
| 692 if (defaultPrevented) { |
| 693 // Tell the JavaScript garbage collector to track lifetime of |dialog| and |
| 694 // call back when the dialog object has been collected. |
| 695 MessagingNatives.BindToGC(dialog, function() { |
| 696 // Avoid showing a warning message if the decision has already been made. |
| 697 if (actionTaken) { |
| 698 return; |
| 699 } |
| 700 WebView.setPermission( |
| 701 self.instanceId, requestId, 'default', '', function(allowed) { |
| 702 if (allowed) { |
| 703 return; |
| 704 } |
| 705 showWarningMessage(event.messageType); |
| 706 }); |
| 707 }); |
| 708 } else { |
| 709 actionTaken = true; |
| 710 // The default action is equivalent to canceling the dialog. |
| 711 WebView.setPermission( |
| 712 self.instanceId, requestId, 'default', '', function(allowed) { |
| 713 if (allowed) { |
| 714 return; |
| 715 } |
| 716 showWarningMessage(event.messageType); |
| 717 }); |
| 718 } |
| 719 }; |
| 720 |
| 721 /** |
| 722 * @private |
| 723 */ |
638 WebViewInternal.prototype.handleLoadAbortEvent = | 724 WebViewInternal.prototype.handleLoadAbortEvent = |
639 function(event, webViewEvent) { | 725 function(event, webViewEvent) { |
640 var showWarningMessage = function(reason) { | 726 var showWarningMessage = function(reason) { |
641 var WARNING_MSG_LOAD_ABORTED = '<webview>: ' + | 727 var WARNING_MSG_LOAD_ABORTED = '<webview>: ' + |
642 'The load has aborted with reason "%1".'; | 728 'The load has aborted with reason "%1".'; |
643 window.console.warn(WARNING_MSG_LOAD_ABORTED.replace('%1', reason)); | 729 window.console.warn(WARNING_MSG_LOAD_ABORTED.replace('%1', reason)); |
644 }; | 730 }; |
645 if (this.webviewNode.dispatchEvent(webViewEvent)) { | 731 if (this.webviewNode.dispatchEvent(webViewEvent)) { |
646 showWarningMessage(event.reason); | 732 showWarningMessage(event.reason); |
647 } | 733 } |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 | 1162 |
1077 /** | 1163 /** |
1078 * Implemented when the experimental API is available. | 1164 * Implemented when the experimental API is available. |
1079 * @private | 1165 * @private |
1080 */ | 1166 */ |
1081 WebViewInternal.prototype.setupExperimentalContextMenus_ = function() {}; | 1167 WebViewInternal.prototype.setupExperimentalContextMenus_ = function() {}; |
1082 | 1168 |
1083 exports.WebView = WebView; | 1169 exports.WebView = WebView; |
1084 exports.WebViewInternal = WebViewInternal; | 1170 exports.WebViewInternal = WebViewInternal; |
1085 exports.CreateEvent = CreateEvent; | 1171 exports.CreateEvent = CreateEvent; |
OLD | NEW |