summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/resources/extensions/web_view_experimental.js
blob: fd7226e5283c96e39c73f6f4149116280eac628a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Shim extension to provide permission request API (and possibly other future
// experimental APIs) for <webview> tag.
// See web_view.js for details.
//
// We want to control the permission API feature in <webview> separately from
// the <webview> feature itself. <webview> is available in stable channel, but
// permission API would only be available for channels CHANNEL_DEV and
// CHANNEL_CANARY.

var WebView = require('webView').WebView;

/** @type {string} */
var REQUEST_TYPE_MEDIA = 'media';

/** @type {string} */
var ERROR_MSG_PERMISSION_ALREADY_DECIDED = '<webview>: ' +
    'Permission has already been decided for this "permissionrequest" event.';

/**
 * @param {!Object} detail The event details, originated from <object>.
 * @private
 */
WebView.prototype.maybeSetupPermissionEvent_ = function() {
  var node = this.node_;
  var objectNode = this.objectNode_;
  this.objectNode_.addEventListener('-internal-permissionrequest', function(e) {
    var evt = new Event('permissionrequest', {bubbles: true, cancelable: true});
    var detail = e.detail ? JSON.parse(e.detail) : {};
    ['permission', 'url'].forEach(function(attribName) {
      evt[attribName] = detail[attribName];
    });
    var requestId = detail.requestId;

    if (detail.permission == REQUEST_TYPE_MEDIA &&
        detail.requestId !== undefined) {
      // 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 {
            objectNode['-internal-setPermission'](requestId, true);
            decisionMade = true;
          }
        },
        deny: function() {
          if (decisionMade) {
            throw new Error(ERROR_MSG_PERMISSION_ALREADY_DECIDED);
          } else {
            objectNode['-internal-setPermission'](requestId, false);
            decisionMade = true;
          }
        }
      };
      evt.request = request;

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

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