OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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. |
| 4 |
| 5 goog.provide('__crweb.dialog_overrides'); |
| 6 |
| 7 // Namespace for this module. |
| 8 __gCrWeb.dialogOverrides = {}; |
| 9 |
| 10 // Beginning of anonymous object. |
| 11 new function() { |
| 12 /* |
| 13 * Install a wrapper around functions displaying dialogs in order to catch |
| 14 * code displaying dialog. |
| 15 * |
| 16 * Since the Javascript on the page may cache the value of those functions |
| 17 * and invoke them later, we must only install the wrapper once and change |
| 18 * their behaviour when required. |
| 19 * |
| 20 * Returns a function that allows changing the value of the two booleans |
| 21 * |suppressDialogs| and |notifyAboutDialogs| that are tested by the wrappers. |
| 22 */ |
| 23 var installDialogOverridesMethods = function() { |
| 24 var suppressDialogs = false; |
| 25 var notifyAboutDialogs = false; |
| 26 |
| 27 // Returns a wrapper function around |originalDialog|. The wrapper may |
| 28 // suppress the dialog and notify host about show/suppress. |
| 29 var makeDialogWrapper = function(originalDialogGetter) { |
| 30 return function() { |
| 31 if (!suppressDialogs) { |
| 32 if (notifyAboutDialogs) { |
| 33 __gCrWeb.message.invokeOnHost({'command': 'dialog.willShow'}); |
| 34 } |
| 35 return originalDialogGetter().apply(null, arguments); |
| 36 } else if (notifyAboutDialogs) { |
| 37 __gCrWeb.message.invokeOnHost({'command': 'dialog.suppressed'}); |
| 38 } |
| 39 }; |
| 40 }; |
| 41 |
| 42 // Install wrapper around the following properties of |window|. |
| 43 var wrappedFunctionNames = ['alert', 'confirm', 'prompt', 'open']; |
| 44 var len = wrappedFunctionNames.length; |
| 45 for (var i = 0; i < len; i++) { |
| 46 (function(wrappedFunctionName) { |
| 47 var wrappedDialogMethod = window[wrappedFunctionName]; |
| 48 window[wrappedFunctionName] = makeDialogWrapper( |
| 49 function() { return wrappedDialogMethod; }); |
| 50 })(wrappedFunctionNames[i]); |
| 51 } |
| 52 |
| 53 // Reading or writing to the property 'geolocation' too early breaks |
| 54 // the API. Make a copy of navigator and stub in the required methods |
| 55 // without touching the property. See crbug.com/280818 for more |
| 56 // details. |
| 57 var stubNavigator = {}; |
| 58 |
| 59 // Copy all properties and functions without touching 'geolocation'. |
| 60 var oldNavigator = navigator; |
| 61 for (var keyName in navigator) { |
| 62 if (keyName !== 'geolocation') { |
| 63 var value = navigator[keyName]; |
| 64 if (typeof(value) == 'function') { |
| 65 // Forward functions calls to real navigator. |
| 66 stubNavigator[keyName] = function() { |
| 67 return value.apply(oldNavigator, arguments); |
| 68 } |
| 69 } else { |
| 70 Object['defineProperty'](stubNavigator, keyName, { |
| 71 value: value, |
| 72 configurable: false, |
| 73 writable: false, |
| 74 enumerable: true |
| 75 }); |
| 76 } |
| 77 } |
| 78 } |
| 79 |
| 80 // Stub in 'geolocation' if necessary, using delayed accessor for the |
| 81 // 'geolocation' property of the original |navigator|. |
| 82 if ('geolocation' in navigator) { |
| 83 var geolocation = {}; |
| 84 var geoPropNames = ['getCurrentPosition', 'watchPosition', 'clearWatch']; |
| 85 var len = geoPropNames.length; |
| 86 for (var i = 0; i < len; i++) { |
| 87 (function(geoPropName) { |
| 88 geolocation[geoPropName] = makeDialogWrapper(function() { |
| 89 return function() { |
| 90 return oldNavigator.geolocation[geoPropName].apply( |
| 91 oldNavigator.geolocation, arguments); |
| 92 }; |
| 93 }); |
| 94 })(geoPropNames[i]); |
| 95 } |
| 96 stubNavigator.geolocation = geolocation; |
| 97 } |
| 98 |
| 99 // Install |stubNavigator| as |navigator|. |
| 100 navigator = stubNavigator; |
| 101 |
| 102 // Returns the closure allowing to change |suppressDialogs| and |
| 103 // |notifyAboutDialogs| variables. |
| 104 return function(setEnabled, setNotify) { |
| 105 suppressDialogs = setEnabled; |
| 106 notifyAboutDialogs = setNotify; |
| 107 }; |
| 108 }; |
| 109 |
| 110 // Override certain methods that produce dialogs. This needs to be installed |
| 111 // after other window methods overrides. |
| 112 __gCrWeb['setSuppressDialogs'] = installDialogOverridesMethods(); |
| 113 |
| 114 } // End of anonymous object |
OLD | NEW |