20
20
import com .google .gwt .thirdparty .guava .common .collect .ImmutableSet ;
21
21
import com .google .gwt .thirdparty .guava .common .collect .Maps ;
22
22
23
- import org .apache .commons .logging .Log ;
24
- import org .apache .commons .logging .LogFactory ;
25
23
import org .htmlunit .AlertHandler ;
26
24
import org .htmlunit .BrowserVersion ;
27
25
import org .htmlunit .FailingHttpStatusCodeException ;
31
29
import org .htmlunit .ScriptException ;
32
30
import org .htmlunit .WebClient ;
33
31
import org .htmlunit .WebWindow ;
34
- import org .htmlunit .corejs .javascript .Context ;
35
- import org .htmlunit .corejs .javascript .Function ;
36
- import org .htmlunit .corejs .javascript .JavaScriptException ;
37
32
import org .htmlunit .corejs .javascript .ScriptableObject ;
38
33
import org .htmlunit .html .HtmlPage ;
39
34
import org .htmlunit .javascript .JavaScriptEngine ;
@@ -67,15 +62,18 @@ protected static class HtmlUnitThread extends Thread implements AlertHandler,
67
62
private final boolean developmentMode ;
68
63
private final TreeLogger treeLogger ;
69
64
private final String url ;
65
+ private final Map <BrowserOption .OptionType , String > properties ;
70
66
private Object waitForUnload = new Object ();
71
67
72
68
public HtmlUnitThread (BrowserVersion browser , String url ,
73
- TreeLogger treeLogger , boolean developmentMode ) {
69
+ TreeLogger treeLogger , boolean developmentMode ,
70
+ Map <BrowserOption .OptionType , String > properties ) {
74
71
this .browser = browser ;
75
72
this .url = url ;
76
73
this .treeLogger = treeLogger ;
77
74
this .setName ("htmlUnit client thread" );
78
75
this .developmentMode = developmentMode ;
76
+ this .properties = properties ;
79
77
}
80
78
81
79
public void handleAlert (Page page , String message ) {
@@ -177,7 +175,7 @@ protected void setupWebClient(WebClient webClient) {
177
175
treeLogger );
178
176
webClient .setJavaScriptEngine (hostedEngine );
179
177
} else {
180
- JavaScriptEngine webEngine = new WebJavaScriptEngine (webClient );
178
+ JavaScriptEngine webEngine = new JavaScriptEngine (webClient );
181
179
webClient .setJavaScriptEngine (webEngine );
182
180
}
183
181
if (System .getProperty ("gwt.htmlunit.debug" ) != null ) {
@@ -207,85 +205,12 @@ private static class HostedJavaScriptEngine extends JavaScriptEngine {
207
205
public void initialize (WebWindow webWindow , Page page ) {
208
206
// Hook in the hosted-mode plugin after initializing the JS engine.
209
207
super .initialize (webWindow , page );
210
- Window window = ( Window ) webWindow .getScriptableObject ();
208
+ Window window = webWindow .getScriptableObject ();
211
209
window .defineProperty ("__gwt_HostedModePlugin" ,
212
210
new HostedModePluginObject (this , webClient , logger ), ScriptableObject .READONLY );
213
211
}
214
212
}
215
213
216
- /**
217
- * JavaScriptEngine subclass that fixes a bug when calling {@code window.onerror}.
218
- * Make sure to remove when updating HtmlUnit.
219
- *
220
- * @see <a href="https://sourceforge.net/p/htmlunit/bugs/1924/">HtmlUnit bug #1924</a>
221
- */
222
- private static class WebJavaScriptEngine extends JavaScriptEngine {
223
- private static final Log LOG = LogFactory .getLog (JavaScriptEngine .class );
224
- private final WebClient webClient ;
225
-
226
- WebJavaScriptEngine (WebClient webClient ) {
227
- super (webClient );
228
- this .webClient = webClient ;
229
- }
230
-
231
- @ Override
232
- protected void handleJavaScriptException (ScriptException scriptException ,
233
- boolean triggerOnError ) {
234
- // XXX(tbroyer): copied from JavaScriptEngine to call below triggerOnError
235
- // instead of Window's triggerOnError.
236
-
237
- // Trigger window.onerror, if it has been set.
238
- final HtmlPage page = scriptException .getPage ();
239
- if (triggerOnError && page != null ) {
240
- final WebWindow window = page .getEnclosingWindow ();
241
- if (window != null ) {
242
- final Window w = (Window ) window .getScriptableObject ();
243
- if (w != null ) {
244
- try {
245
- triggerOnError (w , scriptException );
246
- } catch (final Exception e ) {
247
- handleJavaScriptException (new ScriptException (page , e , null ), false );
248
- }
249
- }
250
- }
251
- }
252
- final JavaScriptErrorListener javaScriptErrorListener =
253
- webClient .getJavaScriptErrorListener ();
254
- if (javaScriptErrorListener != null ) {
255
- javaScriptErrorListener .scriptException (page , scriptException );
256
- }
257
- // Throw a Java exception if the user wants us to.
258
- if (webClient .getOptions ().isThrowExceptionOnScriptError ()) {
259
- throw scriptException ;
260
- }
261
- // Log the error; ScriptException instances provide good debug info.
262
- LOG .info ("Caught script exception" , scriptException );
263
- }
264
-
265
- private void triggerOnError (Window w , ScriptException e ) {
266
- // XXX(tbroyer): copied from HtmlUnit's javascript.host.Window
267
- // with fix unwrapping the JS exception before passing it back to JS.
268
- final Object o = w .getOnerror ();
269
- if (o instanceof Function ) {
270
- final Function f = (Function ) o ;
271
- final String msg = e .getMessage ();
272
- final String url = e .getPage ().getUrl ().toExternalForm ();
273
- final int line = e .getFailingLineNumber ();
274
-
275
- final int column = e .getFailingColumnNumber ();
276
-
277
- Object jsError = null ;
278
- if (e .getCause () instanceof JavaScriptException ) {
279
- jsError = ((JavaScriptException ) e .getCause ()).getValue ();
280
- }
281
-
282
- Object [] args = new Object []{msg , url , line , column , jsError };
283
-
284
- f .call (Context .getCurrentContext (), w , w , args );
285
- }
286
- }
287
- }
288
-
289
214
private static final Map <String , BrowserVersion > BROWSER_MAP = Maps .newHashMap ();
290
215
private static final Map <BrowserVersion , String > USER_AGENT_MAP = Maps .newHashMap ();
291
216
@@ -297,9 +222,7 @@ private void triggerOnError(Window w, ScriptException e) {
297
222
addBrowser (BrowserVersion .CHROME , "safari" );
298
223
}
299
224
300
- private static void addBrowser (BrowserVersion baseBrowser , String userAgent ) {
301
- BrowserVersion browser = new BrowserVersion .BrowserVersionBuilder (baseBrowser )
302
- .setSystemTimezone (TimeZone .getDefault ()).build ();
225
+ private static void addBrowser (BrowserVersion browser , String userAgent ) {
303
226
BROWSER_MAP .put (browser .getNickname (), browser );
304
227
USER_AGENT_MAP .put (browser , userAgent );
305
228
}
@@ -357,7 +280,19 @@ public int initialize(String args) {
357
280
358
281
@ Override
359
282
public void launchModule (String moduleName ) {
360
- for (BrowserVersion browser : browsers ) {
283
+ for (BrowserVersion baseBrowser : browsers ) {
284
+ BrowserVersion .BrowserVersionBuilder builder
285
+ = new BrowserVersion .BrowserVersionBuilder (baseBrowser );
286
+ if (options .containsKey (BrowserOption .OptionType .TIMEZONE )) {
287
+ builder .setSystemTimezone (TimeZone .getTimeZone (
288
+ options .get (BrowserOption .OptionType .TIMEZONE )));
289
+ } else {
290
+ builder .setSystemTimezone (TimeZone .getDefault ());
291
+ }
292
+ if (options .containsKey (BrowserOption .OptionType .LANGUAGE )) {
293
+ builder .setBrowserLanguage (options .get (BrowserOption .OptionType .LANGUAGE ));
294
+ }
295
+ BrowserVersion browser = builder .build ();
361
296
String url = shell .getModuleUrl (moduleName );
362
297
HtmlUnitThread hut = createHtmlUnitThread (browser , url );
363
298
TreeLogger logger = shell .getTopLogger ();
@@ -387,6 +322,6 @@ public boolean setupMode(TreeLogger logger, boolean developmentMode) {
387
322
protected HtmlUnitThread createHtmlUnitThread (BrowserVersion browser ,
388
323
String url ) {
389
324
return new HtmlUnitThread (browser , url , shell .getTopLogger ().branch (
390
- TreeLogger .SPAM , "logging for HtmlUnit thread" ), developmentMode );
325
+ TreeLogger .SPAM , "logging for HtmlUnit thread" ), developmentMode , options );
391
326
}
392
327
}
0 commit comments