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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/resources/extensions/web_view.js
diff --git a/chrome/renderer/resources/extensions/web_view.js b/chrome/renderer/resources/extensions/web_view.js
index 52126d45df008521d26c95737d4d621032970560..7ec4e56d0e580e4e79189e5bb7aaec5b09600051 100644
--- a/chrome/renderer/resources/extensions/web_view.js
+++ b/chrome/renderer/resources/extensions/web_view.js
@@ -36,6 +36,14 @@ var WEB_VIEW_EXT_EVENTS = {
evt: createEvent('webview.onContentLoad'),
fields: []
},
+ '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.
+ cancelable: true,
+ customHandler: function(webview, event, webviewEvent) {
+ webview.maybeSetupExtDialogEvent_(event, webviewEvent);
+ },
+ evt: createEvent('webview.onDialog'),
+ fields: ['defaultPromptText', 'messageText', 'messageType', 'url']
+ },
'exit': {
evt: createEvent('webview.onExit'),
fields: ['processId', 'reason']
@@ -45,13 +53,14 @@ var WEB_VIEW_EXT_EVENTS = {
fields: ['url', 'isTopLevel', 'reason']
},
'loadcommit': {
- customHandler: function(webview, event) {
+ customHandler: function(webview, event, webviewEvent) {
webview.currentEntryIndex_ = event.currentEntryIndex;
webview.entryCount_ = event.entryCount;
webview.processId_ = event.processId;
if (event.isTopLevel) {
webview.browserPluginNode_.setAttribute('src', event.url);
}
+ webview.webviewNode_.dispatchEvent(webviewEvent);
},
evt: createEvent('webview.onLoadCommit'),
fields: ['url', 'isTopLevel']
@@ -68,6 +77,24 @@ var WEB_VIEW_EXT_EVENTS = {
evt: createEvent('webview.onLoadStop'),
fields: []
},
+ 'newwindow': {
+ cancelable: true,
+ customHandler: function(webview, event, webviewEvent) {
+ webview.setupExtNewWindowEvent_(event, webviewEvent);
+ },
+ evt: createEvent('webview.onNewWindow'),
+ 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.
+ 'windowOpenDisposition', 'name']
+ },
+ 'permissionrequest': {
+ cancelable: true,
+ customHandler: function(webview, event, webviewEvent) {
+ webview.setupExtPermissionEvent_(event, webviewEvent);
+ },
+ evt: createEvent('webview.onPermissionRequest'),
+ fields: ['lastUnlockedBySelf', 'permission', 'requestMethod', 'url',
+ 'userGesture']
+ },
'responsive': {
evt: createEvent('webview.onResponsive'),
fields: ['processId']
@@ -361,8 +388,6 @@ WebView.prototype.setupWebviewNodeEvents_ = function() {
for (var eventName in WEB_VIEW_EVENTS) {
this.setupEvent_(eventName, WEB_VIEW_EVENTS[eventName]);
}
- this.setupNewWindowEvent_();
- this.setupPermissionEvent_();
};
/**
@@ -372,12 +397,18 @@ WebView.prototype.setupExtEvent_ = function(eventName, eventInfo) {
var self = this;
var webviewNode = this.webviewNode_;
eventInfo.evt.addListener(function(event) {
- var webviewEvent = new Event(eventName, {bubbles: true});
+ var details = {bubbles:true};
+ if (eventInfo.cancelable)
+ details.cancelable = true;
+ var webviewEvent = new Event(eventName, details);
$Array.forEach(eventInfo.fields, function(field) {
- webviewEvent[field] = event[field];
+ if (event[field] != undefined) {
lazyboy 2013/08/05 09:26:58 use !== undefined
Fady Samuel 2013/08/06 07:14:40 Done.
+ webviewEvent[field] = event[field];
+ }
});
if (eventInfo.customHandler) {
- eventInfo.customHandler(self, event);
+ eventInfo.customHandler(self, event, webviewEvent);
+ return;
}
webviewNode.dispatchEvent(webviewEvent);
}, {instanceId: self.instanceId_});
@@ -402,7 +433,7 @@ WebView.prototype.setupEvent_ = function(eventName, attribs) {
/**
* @private
*/
-WebView.prototype.setupNewWindowEvent_ = function() {
+WebView.prototype.setupExtNewWindowEvent_ = function(event, webviewEvent) {
var ERROR_MSG_NEWWINDOW_ACTION_ALREADY_TAKEN = '<webview>: ' +
'An action has already been taken for this "newwindow" event.';
@@ -416,98 +447,85 @@ WebView.prototype.setupNewWindowEvent_ = function() {
console.warn(WARNING_MSG_NEWWINDOW_BLOCKED);
};
- var NEW_WINDOW_EVENT_ATTRIBUTES = [
- 'initialHeight',
- 'initialWidth',
- 'targetUrl',
- 'windowOpenDisposition',
- 'name'
- ];
-
var self = this;
- var node = this.webviewNode_;
var browserPluginNode = this.browserPluginNode_;
+ var webviewNode = this.webviewNode_;
+
+ var requestId = event.requestId;
+ var actionTaken = false;
var onTrackedObjectGone = function(requestId, e) {
var detail = e.detail ? JSON.parse(e.detail) : {};
if (detail.id != requestId) {
return;
}
- // If the request was pending then show a warning indiciating that a dialog
- // was blocked.
- if (browserPluginNode['-internal-setPermission'](requestId, false, '')) {
- showWarningMessage();
- }
- };
- browserPluginNode.addEventListener('-internal-newwindow', function(e) {
- var evt = new Event('newwindow', { bubbles: true, cancelable: true });
- var detail = e.detail ? JSON.parse(e.detail) : {};
-
- $Array.forEach(NEW_WINDOW_EVENT_ATTRIBUTES, function(attribName) {
- evt[attribName] = detail[attribName];
- });
- var requestId = detail.requestId;
- var actionTaken = false;
+ // Avoid showing a warning message if the decision has already been made.
+ if (actionTaken) {
+ return;
+ }
- var validateCall = function () {
- if (actionTaken) {
- throw new Error(ERROR_MSG_NEWWINDOW_ACTION_ALREADY_TAKEN);
- }
- actionTaken = true;
- };
+ chrome.webview.setPermission(self.instanceId_, requestId, false, '');
+ showWarningMessage();
+ };
- var window = {
- attach: function(webview) {
- validateCall();
- if (!webview)
- throw new Error(ERROR_MSG_WEBVIEW_EXPECTED);
- // Attach happens asynchronously to give the tagWatcher an opportunity
- // to pick up the new webview before attach operates on it, if it hasn't
- // been attached to the DOM already.
- // Note: Any subsequent errors cannot be exceptions because they happen
- // asynchronously.
- setTimeout(function() {
- var attached =
- browserPluginNode['-internal-attachWindowTo'](webview,
- detail.windowId);
- if (!attached) {
- console.error(ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH);
- }
- // If the object being passed into attach is not a valid <webview>
- // then we will fail and it will be treated as if the new window
- // was rejected. The permission API plumbing is used here to clean
- // up the state created for the new window if attaching fails.
- browserPluginNode['-internal-setPermission'](requestId, attached, '');
- }, 0);
- },
- discard: function() {
- validateCall();
- browserPluginNode['-internal-setPermission'](requestId, false, '');
- }
- };
- evt.window = window;
- var defaultPrevented = !node.dispatchEvent(evt);
+ var validateCall = function () {
if (actionTaken) {
- return;
+ throw new Error(ERROR_MSG_NEWWINDOW_ACTION_ALREADY_TAKEN);
}
+ actionTaken = true;
+ };
- if (defaultPrevented) {
- // Make browser plugin track lifetime of |window|.
- var onTrackedObjectGoneWithRequestId =
- $Function.bind(onTrackedObjectGone, self, requestId);
- browserPluginNode.addEventListener('-internal-trackedobjectgone',
- onTrackedObjectGoneWithRequestId);
- browserPluginNode['-internal-trackObjectLifetime'](window, requestId);
- } else {
- actionTaken = true;
- // The default action is to discard the window.
- browserPluginNode['-internal-setPermission'](requestId, false, '');
- showWarningMessage();
+ var window = {
+ attach: function(webview) {
+ validateCall();
+ if (!webview)
+ throw new Error(ERROR_MSG_WEBVIEW_EXPECTED);
+ // Attach happens asynchronously to give the tagWatcher an opportunity
+ // to pick up the new webview before attach operates on it, if it hasn't
+ // been attached to the DOM already.
+ // Note: Any subsequent errors cannot be exceptions because they happen
+ // asynchronously.
+ setTimeout(function() {
+ var attached =
+ browserPluginNode['-internal-attachWindowTo'](webview,
+ event.windowId);
+ if (!attached) {
+ console.error(ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH);
+ }
+ // If the object being passed into attach is not a valid <webview>
+ // then we will fail and it will be treated as if the new window
+ // was rejected. The permission API plumbing is used here to clean
+ // up the state created for the new window if attaching fails.
+ chrome.webview.setPermission(self.instanceId_, requestId, attached, '');
+ }, 0);
+ },
+ discard: function() {
+ validateCall();
+ chrome.webview.setPermission(self.instanceId_, requestId, false, '');
}
+ };
+ webviewEvent.window = window;
- });
+ var defaultPrevented = !webviewNode.dispatchEvent(webviewEvent);
+ if (actionTaken) {
+ return;
+ }
+
+ if (defaultPrevented) {
+ // Make browser plugin track lifetime of |window|.
+ var onTrackedObjectGoneWithRequestId =
+ $Function.bind(onTrackedObjectGone, self, requestId);
+ browserPluginNode.addEventListener('-internal-trackedobjectgone',
+ onTrackedObjectGoneWithRequestId);
+ browserPluginNode['-internal-trackObjectLifetime'](window, requestId);
+ } else {
+ actionTaken = true;
+ // The default action is to discard the window.
+ chrome.webview.setPermission(self.instanceId_, requestId, false, '');
+ showWarningMessage();
+ }
};
/**
@@ -539,10 +557,13 @@ WebView.prototype.setupExecuteCodeAPI_ = function() {
};
/**
- * @param {!Object} detail The event details, originated from <object>.
* @private
*/
-WebView.prototype.setupPermissionEvent_ = function() {
+WebView.prototype.getPermissionTypes_ = function() {
+ return ['media', 'geolocation', 'pointerLock', 'download'];
+};
+
+WebView.prototype.setupExtPermissionEvent_ = function(event, webviewEvent) {
var ERROR_MSG_PERMISSION_ALREADY_DECIDED = '<webview>: ' +
'Permission has already been decided for this "permissionrequest" event.';
@@ -552,89 +573,68 @@ WebView.prototype.setupPermissionEvent_ = function() {
console.warn(WARNING_MSG_PERMISSION_DENIED.replace('%1', permission));
};
- var PERMISSION_TYPES = ['media', 'geolocation', 'pointerLock', 'download'];
-
- var EXPOSED_PERMISSION_EVENT_ATTRIBS = [
- 'lastUnlockedBySelf',
- 'permission',
- 'requestMethod',
- 'url',
- 'userGesture'
- ];
+ var PERMISSION_TYPES = this.getPermissionTypes_();
var self = this;
- var node = this.webviewNode_;
var browserPluginNode = this.browserPluginNode_;
- var internalevent = '-internal-permissionrequest';
+ var webviewNode = this.webviewNode_;
+
+ var requestId = event.requestId;
+ var decisionMade = false;
var onTrackedObjectGone = function(requestId, permission, e) {
var detail = e.detail ? JSON.parse(e.detail) : {};
- if (detail.id != requestId)
+ if (detail.id != requestId) {
return;
- // If the request was pending then show a warning indiciating that the
- // permission was denied.
- if (browserPluginNode['-internal-setPermission'](requestId, false, '')) {
- showWarningMessage(permission);
}
- };
-
- browserPluginNode.addEventListener(internalevent, function(e) {
- var evt = new Event('permissionrequest', {bubbles: true, cancelable: true});
- var detail = e.detail ? JSON.parse(e.detail) : {};
- $Array.forEach(EXPOSED_PERMISSION_EVENT_ATTRIBS, function(attribName) {
- if (detail[attribName] !== undefined)
- evt[attribName] = detail[attribName];
- });
- var requestId = detail.requestId;
- if (detail.requestId == undefined ||
- PERMISSION_TYPES.indexOf(detail.permission) < 0) {
+ // Avoid showing a warning message if the decision has already been made.
+ if (decisionMade) {
return;
}
- // TODO(lazyboy): Also fill in evt.details (see webview specs).
- // http://crbug.com/141197.
- var decisionMade = false;
-
- var validateCall = function() {
- if (decisionMade) {
- throw new Error(ERROR_MSG_PERMISSION_ALREADY_DECIDED);
- }
- decisionMade = true;
- };
-
- // Construct the event.request object.
- var request = {
- allow: function() {
- validateCall();
- browserPluginNode['-internal-setPermission'](requestId, true, '');
- },
- deny: function() {
- validateCall();
- browserPluginNode['-internal-setPermission'](requestId, false, '');
- }
- };
- evt.request = request;
+ chrome.webview.setPermission(self.instanceId_, requestId, false, '');
+ showWarningMessage(permission);
+ };
- var defaultPrevented = !node.dispatchEvent(evt);
+ var validateCall = function() {
if (decisionMade) {
- return;
+ throw new Error(ERROR_MSG_PERMISSION_ALREADY_DECIDED);
}
+ decisionMade = true;
+ };
- if (defaultPrevented) {
- // Make browser plugin track lifetime of |request|.
- var onTrackedObjectGoneWithRequestId =
- $Function.bind(
- onTrackedObjectGone, self, requestId, detail.permission);
- browserPluginNode.addEventListener('-internal-trackedobjectgone',
- onTrackedObjectGoneWithRequestId);
- browserPluginNode['-internal-trackObjectLifetime'](request, requestId);
- } else {
- decisionMade = true;
- browserPluginNode['-internal-setPermission'](requestId, false, '');
- showWarningMessage(detail.permission);
+ // Construct the event.request object.
+ var request = {
+ allow: function() {
+ validateCall();
+ chrome.webview.setPermission(self.instanceId_, requestId, true, '');
+ },
+ deny: function() {
+ validateCall();
+ chrome.webview.setPermission(self.instanceId_, requestId, false, '');
}
- });
+ };
+ webviewEvent.request = request;
+
+ var defaultPrevented = !webviewNode.dispatchEvent(webviewEvent);
+ if (decisionMade) {
+ return;
+ }
+
+ if (defaultPrevented) {
+ // Make browser plugin track lifetime of |request|.
+ var onTrackedObjectGoneWithRequestId =
+ $Function.bind(
+ onTrackedObjectGone, self, requestId, event.permission);
+ browserPluginNode.addEventListener('-internal-trackedobjectgone',
+ onTrackedObjectGoneWithRequestId);
+ browserPluginNode['-internal-trackObjectLifetime'](request, requestId);
+ } else {
+ decisionMade = true;
+ chrome.webview.setPermission(self.instanceId_, requestId, false, '');
+ showWarningMessage(event.permission);
+ }
};
/**
@@ -643,4 +643,10 @@ WebView.prototype.setupPermissionEvent_ = function() {
*/
WebView.prototype.maybeSetupExperimentalAPI_ = function() {};
+/**
+ * Implemented when the experimental API is available.
+ * @private
+ */
+WebView.prototype.maybeSetupExtDialogEvent_ = function() {};
+
exports.WebView = WebView;

Powered by Google App Engine
This is Rietveld 408576698