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

Side by Side Diff: chrome/renderer/resources/extensions/web_view_experimental.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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 extension to provide permission request API (and possibly other future 5 // Shim extension to provide permission request API (and possibly other future
6 // experimental APIs) for <webview> tag. 6 // experimental APIs) for <webview> tag.
7 // See web_view.js for details. 7 // See web_view.js for details.
8 // 8 //
9 // We want to control the permission API feature in <webview> separately from 9 // We want to control the permission API feature in <webview> separately from
10 // the <webview> feature itself. <webview> is available in stable channel, but 10 // the <webview> feature itself. <webview> is available in stable channel, but
11 // permission API would only be available for channels CHANNEL_DEV and 11 // permission API would only be available for channels CHANNEL_DEV and
12 // CHANNEL_CANARY. 12 // CHANNEL_CANARY.
13 13
14 var WebRequestEvent = require('webRequestInternal').WebRequestEvent; 14 var WebRequestEvent = require('webRequestInternal').WebRequestEvent;
15 var webRequestSchema = 15 var webRequestSchema =
16 requireNative('schema_registry').GetSchema('webRequest'); 16 requireNative('schema_registry').GetSchema('webRequest');
17 var WebView = require('webView').WebView; 17 var WebView = require('webView').WebView;
18 18
19 /** 19 /**
20 * @private 20 * @private
21 */ 21 */
22 WebView.prototype.maybeSetupExperimentalAPI_ = function() { 22 WebView.prototype.maybeSetupExperimentalAPI_ = function() {
23 this.setupWebRequestEvents_(); 23 this.setupWebRequestEvents_();
24 this.setupDialogEvent_();
25 }; 24 };
26 25
27 /** 26 /**
28 * @private 27 * @private
29 */ 28 */
30 WebView.prototype.setupWebRequestEvents_ = function() { 29 WebView.prototype.setupWebRequestEvents_ = function() {
31 var self = this; 30 var self = this;
32 // Populate the WebRequest events from the API definition. 31 // Populate the WebRequest events from the API definition.
33 for (var i = 0; i < webRequestSchema.events.length; ++i) { 32 for (var i = 0; i < webRequestSchema.events.length; ++i) {
34 Object.defineProperty(self.webviewNode_, 33 Object.defineProperty(self.webviewNode_,
(...skipping 13 matching lines...) Expand all
48 }(webRequestSchema.events[i]), 47 }(webRequestSchema.events[i]),
49 // No setter. 48 // No setter.
50 enumerable: true 49 enumerable: true
51 }); 50 });
52 } 51 }
53 }; 52 };
54 53
55 /** 54 /**
56 * @private 55 * @private
57 */ 56 */
58 WebView.prototype.setupDialogEvent_ = function() { 57 WebView.prototype.maybeSetupExtDialogEvent_ = function(event, webviewEvent) {
59 var ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN = '<webview>: ' + 58 var ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN = '<webview>: ' +
60 'An action has already been taken for this "dialog" event.'; 59 'An action has already been taken for this "dialog" event.';
61 60
62 var showWarningMessage = function(dialogType) { 61 var showWarningMessage = function(dialogType) {
63 var VOWELS = ['a', 'e', 'i', 'o', 'u']; 62 var VOWELS = ['a', 'e', 'i', 'o', 'u'];
64 var WARNING_MSG_DIALOG_BLOCKED = '<webview>: %1 %2 dialog was blocked.'; 63 var WARNING_MSG_DIALOG_BLOCKED = '<webview>: %1 %2 dialog was blocked.';
65 var article = (VOWELS.indexOf(dialogType.charAt(0)) >= 0) ? 'An' : 'A'; 64 var article = (VOWELS.indexOf(dialogType.charAt(0)) >= 0) ? 'An' : 'A';
66 var output = WARNING_MSG_DIALOG_BLOCKED.replace('%1', article); 65 var output = WARNING_MSG_DIALOG_BLOCKED.replace('%1', article);
67 output = output.replace('%2', dialogType); 66 output = output.replace('%2', dialogType);
68 console.log(output); 67 console.log(output);
69 }; 68 };
70 69
71 var DIALOG_EVENT_ATTRIBUTES = [ 70 var self = this;
72 'defaultPromptText', 71 var browserPluginNode = this.browserPluginNode_;
73 'messageText', 72 var webviewNode = this.webviewNode_;
74 'messageType',
75 'url'
76 ];
77 73
78 var self = this; 74 var requestId = event.requestId;
79 var node = this.webviewNode_; 75 var actionTaken = false;
80 var browserPluginNode = this.browserPluginNode_;
81 76
82 var onTrackedObjectGone = function(requestId, dialogType, e) { 77 var onTrackedObjectGone = function(requestId, dialogType, e) {
83 var detail = e.detail ? JSON.parse(e.detail) : {}; 78 var detail = e.detail ? JSON.parse(e.detail) : {};
84 if (detail.id != requestId) 79 if (detail.id != requestId) {
85 return; 80 return;
86 // If the request was pending then show a warning indiciating that a new
87 // window was blocked.
88 if (browserPluginNode['-internal-setPermission'](requestId, false, '')) {
89 showWarningMessage(dialogType);
90 } 81 }
91 }
92 82
93 browserPluginNode.addEventListener('-internal-dialog', function(e) { 83 // Avoid showing a warning message if the decision has already been made.
94 var evt = new Event('dialog', { bubbles: true, cancelable: true });
95 var detail = e.detail ? JSON.parse(e.detail) : {};
96
97 $Array.forEach(DIALOG_EVENT_ATTRIBUTES, function(attribName) {
98 evt[attribName] = detail[attribName];
99 });
100 var requestId = detail.requestId;
101 var actionTaken = false;
102
103 var validateCall = function() {
104 if (actionTaken) {
105 throw new Error(ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN);
106 }
107 actionTaken = true;
108 };
109
110 var dialog = {
111 ok: function(user_input) {
112 validateCall();
113 browserPluginNode['-internal-setPermission'](
114 requestId, true, user_input);
115 },
116 cancel: function() {
117 validateCall();
118 browserPluginNode['-internal-setPermission'](requestId, false, '');
119 }
120 };
121 evt.dialog = dialog;
122
123 var defaultPrevented = !node.dispatchEvent(evt);
124 if (actionTaken) { 84 if (actionTaken) {
125 return; 85 return;
126 } 86 }
127 87
128 if (defaultPrevented) { 88 chrome.webview.setPermission(self.instanceId_, requestId, false, '');
129 // Tell the JavaScript garbage collector to track lifetime of |dialog| and 89 showWarningMessage(dialogType);
130 // call back when the dialog object has been collected. 90 }
131 var onTrackedObjectGoneWithRequestId = 91
132 $Function.bind( 92 var validateCall = function() {
133 onTrackedObjectGone, self, requestId, detail.messageType); 93 if (actionTaken) {
134 browserPluginNode.addEventListener('-internal-trackedobjectgone', 94 throw new Error(ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN);
135 onTrackedObjectGoneWithRequestId);
136 browserPluginNode['-internal-trackObjectLifetime'](dialog, requestId);
137 } else {
138 actionTaken = true;
139 // The default action is equivalent to canceling the dialog.
140 browserPluginNode['-internal-setPermission'](requestId, false, '');
141 showWarningMessage(detail.messageType);
142 } 95 }
143 }); 96 actionTaken = true;
97 };
98
99 var dialog = {
100 ok: function(user_input) {
101 validateCall();
102 user_input = user_input || '';
103 chrome.webview.setPermission(
104 self.instanceId_, requestId, true, user_input);
105 },
106 cancel: function() {
107 validateCall();
108 chrome.webview.setPermission(self.instanceId_, requestId, false, '');
109 }
110 };
111 webviewEvent.dialog = dialog;
112
113 var defaultPrevented = !webviewNode.dispatchEvent(webviewEvent);
114 if (actionTaken) {
115 return;
116 }
117
118 if (defaultPrevented) {
119 // Tell the JavaScript garbage collector to track lifetime of |dialog| and
120 // call back when the dialog object has been collected.
121 var onTrackedObjectGoneWithRequestId =
122 $Function.bind(
123 onTrackedObjectGone, self, requestId, event.messageType);
124 browserPluginNode.addEventListener('-internal-trackedobjectgone',
125 onTrackedObjectGoneWithRequestId);
126 browserPluginNode['-internal-trackObjectLifetime'](dialog, requestId);
127 } else {
128 actionTaken = true;
129 // The default action is equivalent to canceling the dialog.
130 chrome.webview.setPermission(self.instanceId_, requestId, false, '');
131 showWarningMessage(event.messageType);
132 }
144 }; 133 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698