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.
5 goog
.provide('__crWeb.dialogOverrides');
7 goog
.require('__crWeb.core');
8 // window.open override for dialog suppression must be performed after the rest
9 // of window.open overrides which are done in __crWeb.windowOpen module.
10 goog
.require('__crWeb.windowOpen');
12 // Namespace for this module.
13 __gCrWeb
.dialogOverrides
= {};
15 // Beginning of anonymous object.
18 * Install a wrapper around functions displaying dialogs in order to catch
19 * code displaying dialog.
21 * Since the Javascript on the page may cache the value of those functions
22 * and invoke them later, we must only install the wrapper once and change
23 * their behaviour when required.
25 * Returns a function that allows changing the value of the two booleans
26 * |suppressDialogs| and |notifyAboutDialogs| that are tested by the wrappers.
28 var installDialogOverridesMethods = function() {
29 var suppressDialogs
= false;
30 var notifyAboutDialogs
= false;
32 // Returns a wrapper function around |originalDialog|. The wrapper may
33 // suppress the dialog and notify host about show/suppress.
34 var makeDialogWrapper = function(originalDialogGetter
) {
36 if (!suppressDialogs
) {
37 if (notifyAboutDialogs
) {
38 __gCrWeb
.message
.invokeOnHost({'command': 'dialog.willShow'});
40 return originalDialogGetter().apply(null, arguments
);
41 } else if (notifyAboutDialogs
) {
42 __gCrWeb
.message
.invokeOnHost({'command': 'dialog.suppressed'});
47 // Install wrapper around the following properties of |window|.
48 var wrappedFunctionNames
= ['alert', 'confirm', 'prompt', 'open'];
49 var len
= wrappedFunctionNames
.length
;
50 for (var i
= 0; i
< len
; i
++) {
51 (function(wrappedFunctionName
) {
52 var wrappedDialogMethod
= window
[wrappedFunctionName
];
53 window
[wrappedFunctionName
] = makeDialogWrapper(
54 function() { return wrappedDialogMethod
; });
55 })(wrappedFunctionNames
[i
]);
58 // Reading or writing to the property 'geolocation' too early breaks
59 // the API. Make a copy of navigator and stub in the required methods
60 // without touching the property. See crbug.com/280818 for more
62 var stubNavigator
= {};
64 // Copy all properties and functions without touching 'geolocation'.
65 var oldNavigator
= navigator
;
66 for (var keyName
in navigator
) {
67 if (keyName
!== 'geolocation') {
68 var value
= navigator
[keyName
];
69 if (typeof(value
) == 'function') {
70 // Forward functions calls to real navigator.
71 stubNavigator
[keyName
] = function() {
72 return value
.apply(oldNavigator
, arguments
);
75 Object
['defineProperty'](stubNavigator
, keyName
, {
85 // Stub in 'geolocation' if necessary, using delayed accessor for the
86 // 'geolocation' property of the original |navigator|.
87 if ('geolocation' in navigator
) {
89 var geoPropNames
= ['getCurrentPosition', 'watchPosition', 'clearWatch'];
90 var len
= geoPropNames
.length
;
91 for (var i
= 0; i
< len
; i
++) {
92 (function(geoPropName
) {
93 geolocation
[geoPropName
] = makeDialogWrapper(function() {
95 return oldNavigator
.geolocation
[geoPropName
].apply(
96 oldNavigator
.geolocation
, arguments
);
101 stubNavigator
.geolocation
= geolocation
;
104 // Install |stubNavigator| as |navigator|.
105 /** @suppress {const} */
106 navigator
= stubNavigator
;
108 // Returns the closure allowing to change |suppressDialogs| and
109 // |notifyAboutDialogs| variables.
110 return function(setEnabled
, setNotify
) {
111 suppressDialogs
= setEnabled
;
112 notifyAboutDialogs
= setNotify
;
116 // Override certain methods that produce dialogs. This needs to be installed
117 // after other window methods overrides.
118 __gCrWeb
['setSuppressDialogs'] = installDialogOverridesMethods();
120 }()); // End of anonymous object