web_view_experimental.js revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Shim extension to provide permission request API (and possibly other future 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// experimental APIs) for <webview> tag. 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// See web_view.js for details. 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// We want to control the permission API feature in <webview> separately from 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the <webview> feature itself. <webview> is available in stable channel, but 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// permission API would only be available for channels CHANNEL_DEV and 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// CHANNEL_CANARY. 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)var CreateEvent = require('webView').CreateEvent; 15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)var MessagingNatives = requireNative('messaging_natives'); 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)var WebRequestEvent = require('webRequestInternal').WebRequestEvent; 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)var WebRequestSchema = 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) requireNative('schema_registry').GetSchema('webRequest'); 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)var WebViewInternal = require('webView').WebViewInternal; 20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)var WebView = require('webView').WebView; 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)var WEB_VIEW_EXPERIMENTAL_EVENTS = { 23c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 'dialog': { 24c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch cancelable: true, 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) customHandler: function(webViewInternal, event, webViewEvent) { 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) webViewInternal.handleDialogEvent_(event, webViewEvent); 27c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch }, 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) evt: CreateEvent('webview.onDialog'), 29c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch fields: ['defaultPromptText', 'messageText', 'messageType', 'url'] 30c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 31c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch}; 32c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/** 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * @private 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */ 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)WebViewInternal.prototype.maybeAttachWebRequestEventToWebview_ = 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) function(eventName, webRequestEvent) { 382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch Object.defineProperty( 392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch this.webviewNode_, 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) eventName, 412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch { 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) get: webRequestEvent, 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) enumerable: true 442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 47a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 48a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch/** 49a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @private 50a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch */ 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)WebViewInternal.prototype.handleDialogEvent_ = 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) function(event, webViewEvent) { 53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch var showWarningMessage = function(dialogType) { 54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch var VOWELS = ['a', 'e', 'i', 'o', 'u']; 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch var WARNING_MSG_DIALOG_BLOCKED = '<webview>: %1 %2 dialog was blocked.'; 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch var article = (VOWELS.indexOf(dialogType.charAt(0)) >= 0) ? 'An' : 'A'; 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch var output = WARNING_MSG_DIALOG_BLOCKED.replace('%1', article); 58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch output = output.replace('%2', dialogType); 59c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch console.warn(output); 60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch }; 61a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 62a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch var self = this; 63a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch var browserPluginNode = this.browserPluginNode_; 64c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch var webviewNode = this.webviewNode_; 65c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 66c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch var requestId = event.requestId; 67c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch var actionTaken = false; 68a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 69c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch var validateCall = function() { 70c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch var ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN = '<webview>: ' + 71c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 'An action has already been taken for this "dialog" event.'; 72a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 73558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (actionTaken) { 74c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch throw new Error(ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN); 75558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 76c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch actionTaken = true; 77c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch }; 78558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 79c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch var dialog = { 80c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch ok: function(user_input) { 81c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch validateCall(); 82c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch user_input = user_input || ''; 83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WebView.setPermission(self.instanceId_, requestId, true, user_input); 84c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch }, 85c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch cancel: function() { 86c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch validateCall(); 87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WebView.setPermission(self.instanceId_, requestId, false, ''); 88a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 89c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch }; 90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) webViewEvent.dialog = dialog; 91c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) var defaultPrevented = !webviewNode.dispatchEvent(webViewEvent); 93c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (actionTaken) { 94c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; 95c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 96c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 97c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (defaultPrevented) { 98c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // Tell the JavaScript garbage collector to track lifetime of |dialog| and 99c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // call back when the dialog object has been collected. 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) MessagingNatives.BindToGC(dialog, function() { 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Avoid showing a warning message if the decision has already been made. 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (actionTaken) { 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WebView.setPermission(self.instanceId_, requestId, false, ''); 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) showWarningMessage(event.messageType); 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }); 108c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } else { 109c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch actionTaken = true; 110c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // The default action is equivalent to canceling the dialog. 111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WebView.setPermission(self.instanceId_, requestId, false, ''); 112c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch showWarningMessage(event.messageType); 113c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 114c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch}; 115c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)/** @private */ 117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)WebViewInternal.prototype.maybeGetExperimentalEvents_ = function() { 118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return WEB_VIEW_EXPERIMENTAL_EVENTS; 119a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}; 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)/** @private */ 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)WebViewInternal.prototype.clearData_ = function(var_args) { 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!this.instanceId_) { 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) var args = $Array.concat([this.instanceId_], $Array.slice(arguments)); 127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) $Function.apply(WebView.clearData, null, args); 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)/** @private */ 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WebViewInternal.prototype.getUserAgent_ = function() { 13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return this.userAgentOverride_ || navigator.userAgent; 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)/** @private */ 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WebViewInternal.prototype.isUserAgentOverridden_ = function() { 13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return !!this.userAgentOverride_ && 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) this.userAgentOverride_ != navigator.userAgent; 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)/** @private */ 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WebViewInternal.prototype.setUserAgentOverride_ = function(userAgentOverride) { 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) this.userAgentOverride_ = userAgentOverride; 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!this.instanceId_) { 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If we are not attached yet, then we will pick up the user agent on 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // attachment. 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebView.overrideUserAgent(this.instanceId_, userAgentOverride); 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)WebViewInternal.maybeRegisterExperimentalAPIs = function(proto, secret) { 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) proto.clearData = function(var_args) { 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) var internal = this.internal_(secret); 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) $Function.apply(internal.clearData_, internal, arguments); 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }; 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) proto.getUserAgent = function() { 15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return this.internal_(secret).getUserAgent_(); 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) }; 16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) proto.isUserAgentOverridden = function() { 16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return this.internal_(secret).isUserAgentOverridden_(); 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) }; 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) proto.setUserAgentOverride = function(userAgentOverride) { 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) this.internal_(secret).setUserAgentOverride_(userAgentOverride); 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) }; 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 170