[Android] Added UMA for search by image context menu.
[chromium-blink-merge.git] / chrome / renderer / resources / extensions / web_view_experimental.js
blobc2bb066d6f1b657c0414fd62991597e2f6e75b49
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
3 // found in the LICENSE file.
5 // Shim extension to provide permission request API (and possibly other future
6 // experimental APIs) for <webview> tag.
7 // See web_view.js for details.
8 //
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
11 // permission API would only be available for channels CHANNEL_DEV and
12 // CHANNEL_CANARY.
14 var WebRequestEvent = require('webRequestInternal').WebRequestEvent;
15 var webRequestSchema =
16 requireNative('schema_registry').GetSchema('webRequest');
17 var WebView = require('webView').WebView;
19 /**
20 * @private
22 WebView.prototype.maybeSetupExperimentalAPI_ = function() {
23 this.setupWebRequestEvents_();
24 this.setupDialogEvent_();
27 /**
28 * @private
30 WebView.prototype.setupWebRequestEvents_ = function() {
31 var self = this;
32 var request = {};
33 var createWebRequestEvent = function(webRequestEvent) {
34 return function() {
35 if (!self[webRequestEvent.name + '_']) {
36 self[webRequestEvent.name + '_'] =
37 new WebRequestEvent(
38 'webview.' + webRequestEvent.name,
39 webRequestEvent.parameters,
40 webRequestEvent.extraParameters, null,
41 self.viewInstanceId_);
43 return self[webRequestEvent.name + '_'];
47 // Populate the WebRequest events from the API definition.
48 for (var i = 0; i < webRequestSchema.events.length; ++i) {
49 var webRequestEvent = createWebRequestEvent(webRequestSchema.events[i]);
50 Object.defineProperty(
51 request,
52 webRequestSchema.events[i].name,
54 get: webRequestEvent,
55 enumerable: true
58 Object.defineProperty(
59 this.webviewNode_,
60 webRequestSchema.events[i].name,
62 get: webRequestEvent,
63 enumerable: true
67 Object.defineProperty(
68 this.webviewNode_,
69 'request',
71 value: request,
72 enumerable: true,
73 writable: false
78 /**
79 * @private
81 WebView.prototype.setupDialogEvent_ = function() {
82 var ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN = '<webview>: ' +
83 'An action has already been taken for this "dialog" event.';
85 var showWarningMessage = function(dialogType) {
86 var VOWELS = ['a', 'e', 'i', 'o', 'u'];
87 var WARNING_MSG_DIALOG_BLOCKED = '<webview>: %1 %2 dialog was blocked.';
88 var article = (VOWELS.indexOf(dialogType.charAt(0)) >= 0) ? 'An' : 'A';
89 var output = WARNING_MSG_DIALOG_BLOCKED.replace('%1', article);
90 output = output.replace('%2', dialogType);
91 console.log(output);
94 var DIALOG_EVENT_ATTRIBUTES = [
95 'defaultPromptText',
96 'messageText',
97 'messageType',
98 'url'
101 var self = this;
102 var node = this.webviewNode_;
103 var browserPluginNode = this.browserPluginNode_;
105 var onTrackedObjectGone = function(requestId, dialogType, e) {
106 var detail = e.detail ? JSON.parse(e.detail) : {};
107 if (detail.id != requestId)
108 return;
109 // If the request was pending then show a warning indiciating that a new
110 // window was blocked.
111 if (browserPluginNode['-internal-setPermission'](requestId, false, '')) {
112 showWarningMessage(dialogType);
116 browserPluginNode.addEventListener('-internal-dialog', function(e) {
117 var evt = new Event('dialog', { bubbles: true, cancelable: true });
118 var detail = e.detail ? JSON.parse(e.detail) : {};
120 $Array.forEach(DIALOG_EVENT_ATTRIBUTES, function(attribName) {
121 evt[attribName] = detail[attribName];
123 var requestId = detail.requestId;
124 var actionTaken = false;
126 var validateCall = function() {
127 if (actionTaken) {
128 throw new Error(ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN);
130 actionTaken = true;
133 var dialog = {
134 ok: function(user_input) {
135 validateCall();
136 browserPluginNode['-internal-setPermission'](
137 requestId, true, user_input);
139 cancel: function() {
140 validateCall();
141 browserPluginNode['-internal-setPermission'](requestId, false, '');
144 evt.dialog = dialog;
146 var defaultPrevented = !node.dispatchEvent(evt);
147 if (actionTaken) {
148 return;
151 if (defaultPrevented) {
152 // Tell the JavaScript garbage collector to track lifetime of |dialog| and
153 // call back when the dialog object has been collected.
154 var onTrackedObjectGoneWithRequestId =
155 $Function.bind(
156 onTrackedObjectGone, self, requestId, detail.messageType);
157 browserPluginNode.addEventListener('-internal-trackedobjectgone',
158 onTrackedObjectGoneWithRequestId);
159 browserPluginNode['-internal-trackObjectLifetime'](dialog, requestId);
160 } else {
161 actionTaken = true;
162 // The default action is equivalent to canceling the dialog.
163 browserPluginNode['-internal-setPermission'](requestId, false, '');
164 showWarningMessage(detail.messageType);