2020import com .google .gwt .thirdparty .guava .common .collect .ImmutableSet ;
2121import com .google .gwt .thirdparty .guava .common .collect .Maps ;
2222
23- import org .apache .commons .logging .Log ;
24- import org .apache .commons .logging .LogFactory ;
2523import org .htmlunit .AlertHandler ;
2624import org .htmlunit .BrowserVersion ;
2725import org .htmlunit .FailingHttpStatusCodeException ;
3129import org .htmlunit .ScriptException ;
3230import org .htmlunit .WebClient ;
3331import org .htmlunit .WebWindow ;
34- import org .htmlunit .corejs .javascript .Context ;
35- import org .htmlunit .corejs .javascript .Function ;
36- import org .htmlunit .corejs .javascript .JavaScriptException ;
3732import org .htmlunit .corejs .javascript .ScriptableObject ;
3833import org .htmlunit .html .HtmlPage ;
3934import org .htmlunit .javascript .JavaScriptEngine ;
@@ -67,15 +62,18 @@ protected static class HtmlUnitThread extends Thread implements AlertHandler,
6762 private final boolean developmentMode ;
6863 private final TreeLogger treeLogger ;
6964 private final String url ;
65+ private final Map <BrowserOption .OptionType , String > properties ;
7066 private Object waitForUnload = new Object ();
7167
7268 public HtmlUnitThread (BrowserVersion browser , String url ,
73- TreeLogger treeLogger , boolean developmentMode ) {
69+ TreeLogger treeLogger , boolean developmentMode ,
70+ Map <BrowserOption .OptionType , String > properties ) {
7471 this .browser = browser ;
7572 this .url = url ;
7673 this .treeLogger = treeLogger ;
7774 this .setName ("htmlUnit client thread" );
7875 this .developmentMode = developmentMode ;
76+ this .properties = properties ;
7977 }
8078
8179 public void handleAlert (Page page , String message ) {
@@ -177,7 +175,7 @@ protected void setupWebClient(WebClient webClient) {
177175 treeLogger );
178176 webClient .setJavaScriptEngine (hostedEngine );
179177 } else {
180- JavaScriptEngine webEngine = new WebJavaScriptEngine (webClient );
178+ JavaScriptEngine webEngine = new JavaScriptEngine (webClient );
181179 webClient .setJavaScriptEngine (webEngine );
182180 }
183181 if (System .getProperty ("gwt.htmlunit.debug" ) != null ) {
@@ -207,85 +205,12 @@ private static class HostedJavaScriptEngine extends JavaScriptEngine {
207205 public void initialize (WebWindow webWindow , Page page ) {
208206 // Hook in the hosted-mode plugin after initializing the JS engine.
209207 super .initialize (webWindow , page );
210- Window window = ( Window ) webWindow .getScriptableObject ();
208+ Window window = webWindow .getScriptableObject ();
211209 window .defineProperty ("__gwt_HostedModePlugin" ,
212210 new HostedModePluginObject (this , webClient , logger ), ScriptableObject .READONLY );
213211 }
214212 }
215213
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-
289214 private static final Map <String , BrowserVersion > BROWSER_MAP = Maps .newHashMap ();
290215 private static final Map <BrowserVersion , String > USER_AGENT_MAP = Maps .newHashMap ();
291216
@@ -297,9 +222,7 @@ private void triggerOnError(Window w, ScriptException e) {
297222 addBrowser (BrowserVersion .CHROME , "safari" );
298223 }
299224
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 ) {
303226 BROWSER_MAP .put (browser .getNickname (), browser );
304227 USER_AGENT_MAP .put (browser , userAgent );
305228 }
@@ -357,7 +280,19 @@ public int initialize(String args) {
357280
358281 @ Override
359282 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 ();
361296 String url = shell .getModuleUrl (moduleName );
362297 HtmlUnitThread hut = createHtmlUnitThread (browser , url );
363298 TreeLogger logger = shell .getTopLogger ();
@@ -387,6 +322,6 @@ public boolean setupMode(TreeLogger logger, boolean developmentMode) {
387322 protected HtmlUnitThread createHtmlUnitThread (BrowserVersion browser ,
388323 String url ) {
389324 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 );
391326 }
392327}
0 commit comments