Skip to content

Commit

Permalink
<webview>: Mark permissionrequest API as stable.
Browse files Browse the repository at this point in the history
BUG=none

Review URL: https://chromiumcodereview.appspot.com/17395004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207104 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
fsamuel@chromium.org committed Jun 18, 2013
1 parent a35c5e0 commit 5f20999
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 67 deletions.
86 changes: 86 additions & 0 deletions chrome/renderer/resources/extensions/web_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ WebView.prototype.setupWebviewNodeEvents_ = function() {
this.setupEvent_(eventName, WEB_VIEW_EVENTS[eventName]);
}
this.setupNewWindowEvent_();
this.setupPermissionEvent_();
};

/**
Expand Down Expand Up @@ -386,6 +387,91 @@ WebView.prototype.setupExecuteCodeAPI_ = function() {
}
};

/**
* @private
*/
WebView.prototype.getPermissionTypes_ = function() {
var PERMISSION_TYPES = ['media', 'geolocation', 'pointerLock'];
return PERMISSION_TYPES.concat(this.maybeGetExperimentalPermissionTypes_());
};

/**
* @param {!Object} detail The event details, originated from <object>.
* @private
*/
WebView.prototype.setupPermissionEvent_ = function() {
var PERMISSION_TYPES = this.getPermissionTypes_();

var EXPOSED_PERMISSION_EVENT_ATTRIBS = [
'lastUnlockedBySelf',
'permission',
'requestMethod',
'url',
'userGesture'
];

var ERROR_MSG_PERMISSION_ALREADY_DECIDED = '<webview>: ' +
'Permission has already been decided for this "permissionrequest" event.';

var node = this.webviewNode_;
var browserPluginNode = this.browserPluginNode_;
var internalevent = '-internal-permissionrequest';
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) {
// TODO(lazyboy): Also fill in evt.details (see webview specs).
// http://crbug.com/141197.
var decisionMade = false;
// Construct the event.request object.
var request = {
allow: function() {
if (decisionMade) {
throw new Error(ERROR_MSG_PERMISSION_ALREADY_DECIDED);
} else {
browserPluginNode['-internal-setPermission'](requestId, true);
decisionMade = true;
}
},
deny: function() {
if (decisionMade) {
throw new Error(ERROR_MSG_PERMISSION_ALREADY_DECIDED);
} else {
browserPluginNode['-internal-setPermission'](requestId, false);
decisionMade = true;
}
}
};
evt.request = request;

// Make browser plugin track lifetime of |request|.
browserPluginNode['-internal-persistObject'](
request, detail.permission, requestId);

var defaultPrevented = !node.dispatchEvent(evt);
if (!decisionMade && !defaultPrevented) {
decisionMade = true;
browserPluginNode['-internal-setPermission'](requestId, false);
}
}
});
};

/**
* Implemented when the experimental API is available.
* @private
*/
WebView.prototype.maybeGetExperimentalPermissionTypes_ = function() {
return [];
};

/**
* Implemented when the experimental API is available.
* @private
Expand Down
71 changes: 4 additions & 67 deletions chrome/renderer/resources/extensions/web_view_experimental.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,82 +16,19 @@ var webRequestSchema =
requireNative('schema_registry').GetSchema('webRequest');
var WebView = require('webView').WebView;

/** @type {Array.<string>} */
var PERMISSION_TYPES = ['download', 'media', 'geolocation', 'pointerLock'];

var EXPOSED_PERMISSION_EVENT_ATTRIBS = [
'lastUnlockedBySelf',
'permission',
'requestMethod',
'url',
'userGesture'
];

/**
* @private
*/
WebView.prototype.maybeSetupExperimentalAPI_ = function() {
this.setupPermissionEvent_();
this.setupWebRequestEvents_();
}
};

/**
* @param {!Object} detail The event details, originated from <object>.
* @private
*/
WebView.prototype.setupPermissionEvent_ = function() {
var ERROR_MSG_PERMISSION_ALREADY_DECIDED = '<webview>: ' +
'Permission has already been decided for this "permissionrequest" event.';

var node = this.webviewNode_;
var browserPluginNode = this.browserPluginNode_;
var internalevent = '-internal-permissionrequest';
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) {
// TODO(lazyboy): Also fill in evt.details (see webview specs).
// http://crbug.com/141197.
var decisionMade = false;
// Construct the event.request object.
var request = {
allow: function() {
if (decisionMade) {
throw new Error(ERROR_MSG_PERMISSION_ALREADY_DECIDED);
} else {
browserPluginNode['-internal-setPermission'](requestId, true);
decisionMade = true;
}
},
deny: function() {
if (decisionMade) {
throw new Error(ERROR_MSG_PERMISSION_ALREADY_DECIDED);
} else {
browserPluginNode['-internal-setPermission'](requestId, false);
decisionMade = true;
}
}
};
evt.request = request;

// Make browser plugin track lifetime of |request|.
browserPluginNode['-internal-persistObject'](
request, detail.permission, requestId);

var defaultPrevented = !node.dispatchEvent(evt);
if (!decisionMade && !defaultPrevented) {
decisionMade = true;
browserPluginNode['-internal-setPermission'](requestId, false);
}
}
});
WebView.prototype.maybeGetExperimentalPermissionTypes_ = function() {
var PERMISSION_TYPES = ['download'];
return PERMISSION_TYPES;
};

/**
Expand Down

0 comments on commit 5f20999

Please sign in to comment.