- add sources.
[platform/framework/web/crosswalk.git] / src / chrome_frame / cfinstall / src / stub / prompt.js
1 // Copyright (c) 2011 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 /**
6  * @fileoverview Implements an in-site integration of the Chrome Frame
7  * installation flow by loading its implementation on demand.
8  **/
9
10 goog.provide('google.cf.installer.Prompt');
11
12 goog.require('google.cf.installer.InteractionDelegate');
13
14 /**
15  * Constructs a prompt flow that loads its implementation from an external
16  * Javascript file.
17  * @constructor
18  * @param {Window=} opt_windowInstance The window in which to load the external
19  *     script. Defaults to the global window object.
20  */
21 google.cf.installer.Prompt = function(opt_windowInstance) {
22   this.window_ = opt_windowInstance || window;
23 };
24
25 /**
26  * An optional adapter to customize the display of the installation flow.
27  * @type {!google.cf.installer.InteractionDelegate|undefined}
28  * @private
29  */
30 google.cf.installer.Prompt.prototype.customInteractionDelegate_ = undefined;
31
32 /**
33  * An optional URL to a resource in the same domain as the calling site that
34  * will be used to transport installation results back to the client.
35  */
36 google.cf.installer.Prompt.prototype.
37     manuallySpecifiedSameDomainResourceUri_ = undefined;
38
39 /**
40  * Customizes the display of the prompt via the given adapter.
41  * @param {!google.cf.installer.InteractionDelegate} interactionDelegate The
42  *     adapter.
43  */
44 google.cf.installer.Prompt.prototype.setInteractionDelegate =
45     function(interactionDelegate) {
46   this.customInteractionDelegate_ = interactionDelegate;
47 };
48
49 /**
50  * Specifies a resource in the same domain as the calling site that will be used
51  * to carry installation results across domain boundaries.
52  * @param {string} uri The resource URI to use.
53  */
54 google.cf.installer.Prompt.prototype.setSameDomainResourceUri = function(uri) {
55   this.manuallySpecifiedSameDomainResourceUri_ = uri;
56 };
57
58 /**
59  * Holds the loaded installation flow execution method. See
60  * CrossDomainInstall.execute (crossdomaininstall.js).
61  * @type {?function(function(), function()=, string=,
62  *                  google.cf.installer.InteractionDelegate=, string=)}
63  * @private
64  **/
65 google.cf.installer.Prompt.prototype.installProc_ = null;
66
67 /**
68  * @define {string} Defines the default implementation location.
69  **/
70 google.cf.installer.Prompt.DEFAULT_IMPLEMENTATION_URL =
71     '//ajax.googleapis.com/ajax/libs/chrome-frame/2/CFInstall.impl.min.js';
72
73 /**
74  * Defines the URL from which the full prompting logic will be retrieved.
75  * @type {string}
76  * @private
77  **/
78 google.cf.installer.Prompt.prototype.implementationUrl_ =
79     google.cf.installer.Prompt.DEFAULT_IMPLEMENTATION_URL;
80
81 /**
82  * Defines a custom URL for the Chrome Frame download page.
83  * @type {string|undefined}
84  * @private
85  */
86 google.cf.installer.Prompt.prototype.downloadPageUrl_ = undefined;
87
88 /**
89  * Overrides the default URL for loading the implementation.
90  * @param {string} url The custom URL.
91  */
92 google.cf.installer.Prompt.prototype.setImplementationUrl = function(url) {
93   this.implementationUrl_ = url;
94 };
95
96 /**
97  * Overrides the default URL for the download page.
98  * @param {string} url The custom URL.
99  */
100 google.cf.installer.Prompt.prototype.setDownloadPageUrl = function(url) {
101   this.downloadPageUrl_ = url;
102 };
103
104 /**
105  * Initiates loading of the full implementation if not already initiated.
106  * @param {function()=} opt_loadCompleteHandler A callback that will be notified
107  *     when the loading of the script has completed, possibly unsuccessfully.
108  **/
109 google.cf.installer.Prompt.prototype.loadInstallProc_ =
110     function(opt_loadCompleteHandler) {
111   var scriptParent = this.window_.document.getElementsByTagName('head')[0] ||
112       this.window_.document.documentElement;
113   var scriptEl = this.window_.document.createElement('script');
114   scriptEl.src = this.implementationUrl_;
115   scriptEl.type = 'text/javascript';
116
117   if (opt_loadCompleteHandler) {
118     var loadHandler = goog.bind(function() {
119       scriptEl.onreadystatechange = null;
120       scriptEl.onerror = null;
121       scriptEl.onload = null;
122       loadHandler = function(){};
123       opt_loadCompleteHandler();
124     }, this);
125
126     scriptEl.onload = loadHandler;
127     scriptEl.onerror = loadHandler;
128     scriptEl.onreadystatechange = function() {
129       if (scriptEl.readyState == 'loaded')
130         loadHandler();
131     };
132   }
133
134   scriptParent.appendChild(scriptEl);
135 };
136
137 /**
138  * Invokes the installation procedure with our configured parameters and
139  * the provided callbacks.
140  * @param {function()} successHandler The method to invoke upon installation
141  *     success.
142  * @param {function()} opt_failureHandler The method to invoke upon installation
143  *     failure.
144  */
145 google.cf.installer.Prompt.prototype.invokeProc_ =
146     function(successHandler, opt_failureHandler) {
147   this.installProc_(successHandler,
148                     opt_failureHandler,
149                     this.downloadPageUrl_,
150                     this.customInteractionDelegate_,
151                     this.manuallySpecifiedSameDomainResourceUri_);
152 }
153
154 /**
155  * Receives a handle to the flow implementation method and invokes it.
156  * @param {function(function(), function()=, string=,
157  *                  google.cf.installer.InteractionDelegate=, string=)}
158  *     installProc The install execution method. See
159  *     CrossDomainInstall.execute().
160  * @param {function()} successHandler The method to invoke upon installation
161  *     success.
162  * @param {function()} opt_failureHandler The method to invoke upon installation
163  *     failure.
164  */
165 google.cf.installer.Prompt.prototype.onProcLoaded_ =
166     function(installProc, successHandler, opt_failureHandler) {
167   this.window_['CF_google_cf_xd_install_stub'] = undefined;
168   this.installProc_ = installProc;
169   this.invokeProc_(successHandler, opt_failureHandler);
170 };
171
172 /**
173  * Loads and executes the in-line Google Chrome Frame installation flow.
174  * Will typically execute asynchronously (as the flow behaviour is not yet
175  * loaded).
176  *
177  * @param {function()} successHandler A function to invoke once Google
178  *     Chrome Frame is successfully installed. Overrides the default
179  *     behaviour, which is to reload the current page.
180  * @param {function()=} opt_failureHandler A function to invoke if the
181  *     installation fails. The default behaviour is to do nothing.
182  */
183 google.cf.installer.Prompt.prototype.open = function(successHandler,
184                                                      opt_failureHandler) {
185   if (this.installProc_) {
186     this.invokeProc_(successHandler, opt_failureHandler);
187     return;
188   }
189
190   if (this.window_['CF_google_cf_xd_install_stub']) {
191     if (opt_failureHandler)
192       opt_failureHandler();
193     return;
194   }
195
196   this.window_['CF_google_cf_xd_install_stub'] = goog.bind(
197     function(installProc) {
198       this.onProcLoaded_(installProc, successHandler, opt_failureHandler);
199     }, this);
200
201   var loadCompleteHandler = undefined;
202   if (opt_failureHandler) {
203     loadCompleteHandler = goog.bind(function() {
204       if (!this.installProc_)
205         opt_failureHandler();
206     }, this);
207   }
208
209   this.loadInstallProc_(loadCompleteHandler);
210 };