Index: ios/web/web_state/js/resources/dialog_overrides.js |
diff --git a/ios/web/web_state/js/resources/dialog_overrides.js b/ios/web/web_state/js/resources/dialog_overrides.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d5c582ef51fe60bcf84caf70b8fc2790acf43a85 |
--- /dev/null |
+++ b/ios/web/web_state/js/resources/dialog_overrides.js |
@@ -0,0 +1,114 @@ |
+// Copyright 2014 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. |
+ |
+goog.provide('__crweb.dialog_overrides'); |
+ |
+// Namespace for this module. |
+__gCrWeb.dialogOverrides = {}; |
+ |
+// Beginning of anonymous object. |
+new function() { |
+ /* |
+ * Install a wrapper around functions displaying dialogs in order to catch |
+ * code displaying dialog. |
+ * |
+ * Since the Javascript on the page may cache the value of those functions |
+ * and invoke them later, we must only install the wrapper once and change |
+ * their behaviour when required. |
+ * |
+ * Returns a function that allows changing the value of the two booleans |
+ * |suppressDialogs| and |notifyAboutDialogs| that are tested by the wrappers. |
+ */ |
+ var installDialogOverridesMethods = function() { |
+ var suppressDialogs = false; |
+ var notifyAboutDialogs = false; |
+ |
+ // Returns a wrapper function around |originalDialog|. The wrapper may |
+ // suppress the dialog and notify host about show/suppress. |
+ var makeDialogWrapper = function(originalDialogGetter) { |
+ return function() { |
+ if (!suppressDialogs) { |
+ if (notifyAboutDialogs) { |
+ __gCrWeb.message.invokeOnHost({'command': 'dialog.willShow'}); |
+ } |
+ return originalDialogGetter().apply(null, arguments); |
+ } else if (notifyAboutDialogs) { |
+ __gCrWeb.message.invokeOnHost({'command': 'dialog.suppressed'}); |
+ } |
+ }; |
+ }; |
+ |
+ // Install wrapper around the following properties of |window|. |
+ var wrappedFunctionNames = ['alert', 'confirm', 'prompt', 'open']; |
+ var len = wrappedFunctionNames.length; |
+ for (var i = 0; i < len; i++) { |
+ (function(wrappedFunctionName) { |
+ var wrappedDialogMethod = window[wrappedFunctionName]; |
+ window[wrappedFunctionName] = makeDialogWrapper( |
+ function() { return wrappedDialogMethod; }); |
+ })(wrappedFunctionNames[i]); |
+ } |
+ |
+ // Reading or writing to the property 'geolocation' too early breaks |
+ // the API. Make a copy of navigator and stub in the required methods |
+ // without touching the property. See crbug.com/280818 for more |
+ // details. |
+ var stubNavigator = {}; |
+ |
+ // Copy all properties and functions without touching 'geolocation'. |
+ var oldNavigator = navigator; |
+ for (var keyName in navigator) { |
+ if (keyName !== 'geolocation') { |
+ var value = navigator[keyName]; |
+ if (typeof(value) == 'function') { |
+ // Forward functions calls to real navigator. |
+ stubNavigator[keyName] = function() { |
+ return value.apply(oldNavigator, arguments); |
+ } |
+ } else { |
+ Object['defineProperty'](stubNavigator, keyName, { |
+ value: value, |
+ configurable: false, |
+ writable: false, |
+ enumerable: true |
+ }); |
+ } |
+ } |
+ } |
+ |
+ // Stub in 'geolocation' if necessary, using delayed accessor for the |
+ // 'geolocation' property of the original |navigator|. |
+ if ('geolocation' in navigator) { |
+ var geolocation = {}; |
+ var geoPropNames = ['getCurrentPosition', 'watchPosition', 'clearWatch']; |
+ var len = geoPropNames.length; |
+ for (var i = 0; i < len; i++) { |
+ (function(geoPropName) { |
+ geolocation[geoPropName] = makeDialogWrapper(function() { |
+ return function() { |
+ return oldNavigator.geolocation[geoPropName].apply( |
+ oldNavigator.geolocation, arguments); |
+ }; |
+ }); |
+ })(geoPropNames[i]); |
+ } |
+ stubNavigator.geolocation = geolocation; |
+ } |
+ |
+ // Install |stubNavigator| as |navigator|. |
+ navigator = stubNavigator; |
+ |
+ // Returns the closure allowing to change |suppressDialogs| and |
+ // |notifyAboutDialogs| variables. |
+ return function(setEnabled, setNotify) { |
+ suppressDialogs = setEnabled; |
+ notifyAboutDialogs = setNotify; |
+ }; |
+ }; |
+ |
+ // Override certain methods that produce dialogs. This needs to be installed |
+ // after other window methods overrides. |
+ __gCrWeb['setSuppressDialogs'] = installDialogOverridesMethods(); |
+ |
+} // End of anonymous object |