[HtmlUnit] SVN: [15418] trunk/htmlunit/src
rbri--- via HtmlUnit-develop <[email protected]>
| Newsgroups | gmane.comp.java.htmlunit.devel |
|---|---|
| Message-ID | <[email protected]> |
Revision: 15418
http://sourceforge.net/p/htmlunit/code/15418
Author: rbri
Date: 2018-06-29 19:51:23 +0000 (Fri, 29 Jun 2018)
Log Message:
-----------
Correct handling of additional parameters provided in functions setTimeout/setInterval.
Issue 1966
Modified Paths:
--------------
trunk/htmlunit/src/changes/changes.xml
trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BackgroundJavaScriptFactory.java
trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptFunctionJob.java
trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java
Modified: trunk/htmlunit/src/changes/changes.xml
===================================================================
--- trunk/htmlunit/src/changes/changes.xml 2018-06-29 17:33:58 UTC (rev 15417)
+++ trunk/htmlunit/src/changes/changes.xml 2018-06-29 19:51:23 UTC (rev 15418)
@@ -14,6 +14,9 @@
<action type="remove" dev="rbri">
FF45 support removed.
</action>
+ <action type="fix" dev="rbri" issue="1966" due-to="Atsushi Nakagawa">
+ Correct handling of additional parameters provided in functions setTimeout/setInterval.
+ </action>
<action type="fix" dev="rbri" issue="1964">
NPE in HtmlTextArea.removeFocus().
</action>
Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BackgroundJavaScriptFactory.java
===================================================================
--- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BackgroundJavaScriptFactory.java 2018-06-29 17:33:58 UTC (rev 15417)
+++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BackgroundJavaScriptFactory.java 2018-06-29 19:51:23 UTC (rev 15418)
@@ -28,6 +28,7 @@
* JavaScript engine.
*
* @author Ronald Brill
+ * @author Atsushi Nakagawa
*/
public class BackgroundJavaScriptFactory {
@@ -73,13 +74,14 @@
* @param label the label for the job
* @param window the window to which the job belongs
* @param function the JavaScript code to execute
+ * @param args the arguments to pass into the function call
*
* @return JavaScriptJob the created job
*/
public JavaScriptFunctionJob createJavaScriptJob(final int initialDelay,
final Integer period, final String label,
- final WebWindow window, final Function function) {
- return new JavaScriptFunctionJob(initialDelay, period, label, window, function);
+ final WebWindow window, final Function function, final Object[] args) {
+ return new JavaScriptFunctionJob(initialDelay, period, label, window, function, args);
}
/**
Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptFunctionJob.java
===================================================================
--- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptFunctionJob.java 2018-06-29 17:33:58 UTC (rev 15417)
+++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptFunctionJob.java 2018-06-29 19:51:23 UTC (rev 15418)
@@ -24,11 +24,14 @@
/**
* A {@link JavaScriptJob} created from a {@link Function} object.
* @author Brad Clarke
+ * @author Ronald Brill
+ * @author Atsushi Nakagawa
*/
class JavaScriptFunctionJob extends JavaScriptExecutionJob {
/** The JavaScript code to execute. */
private final Function function_;
+ private final Object[] args_;
/**
* Creates a new JavaScript execution job, where the JavaScript code to execute is a function.
@@ -37,11 +40,13 @@
* @param label the label for the job
* @param window the window to which the job belongs
* @param function the JavaScript code to execute
+ * @param args the arguments to pass into the function call
*/
JavaScriptFunctionJob(final int initialDelay, final Integer period, final String label,
- final WebWindow window, final Function function) {
+ final WebWindow window, final Function function, final Object[] args) {
super(initialDelay, period, label, window);
function_ = function;
+ args_ = args;
}
/** {@inheritDoc} */
@@ -49,7 +54,7 @@
protected void runJavaScript(final HtmlPage page) {
final DomElement doc = page.getDocumentElement();
final Scriptable scriptable = page.getEnclosingWindow().getScriptableObject();
- page.executeJavaScriptFunction(function_, scriptable, new Object[0], doc);
+ page.executeJavaScriptFunction(function_, scriptable, args_, doc);
}
}
Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java
===================================================================
--- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2018-06-29 17:33:58 UTC (rev 15417)
+++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2018-06-29 19:51:23 UTC (rev 15418)
@@ -24,8 +24,8 @@
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import java.io.IOException;
@@ -155,6 +155,7 @@
* @author Frank Danek
* @author Carsten Steul
* @author Colin Alworth
+ * @author Atsushi Nakagawa
* @see <a href="http://msdn.microsoft.com/en-us/library/ms535873.aspx">MSDN documentation</a>
*/
@JsxClass
@@ -483,32 +484,77 @@
* The invocation occurs only if the window is opened after the delay
* and does not contain an other page than the one that originated the setTimeout.
*
- * @param code specifies the function pointer or string that indicates the code to be executed
- * when the specified interval has elapsed
- * @param timeout specifies the number of milliseconds
- * @param language specifies language
+ * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">
+ * MDN web docs</a>
+ *
+ * @param context the JavaScript context
+ * @param thisObj the scriptable
+ * @param args the arguments passed into the method
+ * @param function the function
* @return the id of the created timer
*/
@JsxFunction
- public int setTimeout(final Object code, int timeout, final Object language) {
+ public static Object setTimeout(final Context context, final Scriptable thisObj,
+ final Object[] args, final Function function) {
+ if (args.length < 1) {
+ throw ScriptRuntime.typeError("Function not provided");
+ }
+
+ final int timeout = ScriptRuntime.toInt32((args.length > 1) ? args[1] : Undefined.instance);
+ final Object[] params = (args.length > 2)
+ ? Arrays.copyOfRange(args, 2, args.length)
+ : ScriptRuntime.emptyArgs;
+ return ((Window) thisObj).setTimeoutIntervalImpl(args[0], timeout, true, params);
+ }
+
+ /**
+ * Sets a chunk of JavaScript to be invoked each time a specified number of milliseconds has elapsed.
+ *
+ * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">
+ * MDN web docs</a>
+ * @param context the JavaScript context
+ * @param thisObj the scriptable
+ * @param args the arguments passed into the method
+ * @param function the function
+ * @return the id of the created interval
+ */
+ @JsxFunction
+ public static Object setInterval(final Context context, final Scriptable thisObj,
+ final Object[] args, final Function function) {
+ if (args.length < 1) {
+ throw ScriptRuntime.typeError("Function not provided");
+ }
+
+ final int timeout = ScriptRuntime.toInt32((args.length > 1) ? args[1] : Undefined.instance);
+ final Object[] params = (args.length > 2)
+ ? Arrays.copyOfRange(args, 2, args.length)
+ : ScriptRuntime.emptyArgs;
+ return ((Window) thisObj).setTimeoutIntervalImpl(args[0], timeout, false, params);
+ }
+
+ private int setTimeoutIntervalImpl(final Object code, int timeout, final boolean isTimeout, final Object[] params) {
if (timeout < MIN_TIMER_DELAY) {
timeout = MIN_TIMER_DELAY;
}
- if (code == null) {
- throw Context.reportRuntimeError("Function not provided.");
- }
- final int id;
final WebWindow webWindow = getWebWindow();
final Page page = (Page) getDomNodeOrNull();
+ Integer period = null;
+ if (!isTimeout) {
+ period = Integer.valueOf(timeout);
+ }
+
if (code instanceof String) {
final String s = (String) code;
- final String description = "window.setTimeout(" + s + ", " + timeout + ")";
+ final String description = "window.set"
+ + (isTimeout ? "Timeout" : "Interval")
+ + "(" + s + ", " + timeout + ")";
final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
- createJavaScriptJob(timeout, null, description, webWindow, s);
- id = webWindow.getJobManager().addJob(job, page);
+ createJavaScriptJob(timeout, period, description, webWindow, s);
+ return webWindow.getJobManager().addJob(job, page);
}
- else if (code instanceof Function) {
+
+ if (code instanceof Function) {
final Function f = (Function) code;
final String functionName;
if (f instanceof FunctionObject) {
@@ -518,15 +564,15 @@
functionName = String.valueOf(f); // can this happen?
}
- final String description = "window.setTimeout(" + functionName + ", " + timeout + ")";
+ final String description = "window.set"
+ + (isTimeout ? "Timeout" : "Interval")
+ + "(" + functionName + ", " + timeout + ")";
final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
- createJavaScriptJob(timeout, null, description, webWindow, f);
- id = webWindow.getJobManager().addJob(job, page);
+ createJavaScriptJob(timeout, period, description, webWindow, f, params);
+ return webWindow.getJobManager().addJob(job, page);
}
- else {
- throw Context.reportRuntimeError("Unknown type for function.");
- }
- return id;
+
+ throw Context.reportRuntimeError("Unknown type for function.");
}
/**
@@ -543,6 +589,21 @@
}
/**
+ * Cancels the interval previously started using the {@link #setInterval(Object, int, Object)} method.
+ * Current implementation does nothing.
+ * @param intervalID specifies the interval to cancel as returned by the
+ * {@link #setInterval(Object, int, Object)} method
+ * @see <a href="http://msdn.microsoft.com/en-us/library/ms536353.aspx">MSDN documentation</a>
+ */
+ @JsxFunction
+ public void clearInterval(final int intervalID) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("clearInterval(" + intervalID + ")");
+ }
+ getWebWindow().getJobManager().removeJob(intervalID);
+ }
+
+ /**
* Returns the JavaScript property {@code navigator}.
* @return the navigator
*/
@@ -1487,61 +1548,6 @@
}
/**
- * Sets a chunk of JavaScript to be invoked each time a specified number of milliseconds has elapsed.
- *
- * @see <a href="http://msdn.microsoft.com/en-us/library/ms536749.aspx">MSDN documentation</a>
- * @param code specifies the function pointer or string that indicates the code to be executed
- * when the specified interval has elapsed
- * @param timeout specifies the number of milliseconds
- * @param language specifies language
- * @return the id of the created interval
- */
- @JsxFunction
- public int setInterval(final Object code, int timeout, final Object language) {
- if (timeout < MIN_TIMER_DELAY) {
- timeout = MIN_TIMER_DELAY;
- }
- final int id;
- final WebWindow w = getWebWindow();
- final Page page = (Page) getDomNodeOrNull();
- final String description = "window.setInterval(" + timeout + ")";
- if (code == null) {
- throw Context.reportRuntimeError("Function not provided.");
- }
- else if (code instanceof String) {
- final String s = (String) code;
- final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
- createJavaScriptJob(timeout, Integer.valueOf(timeout), description, w, s);
- id = w.getJobManager().addJob(job, page);
- }
- else if (code instanceof Function) {
- final Function f = (Function) code;
- final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
- createJavaScriptJob(timeout, Integer.valueOf(timeout), description, w, f);
- id = w.getJobManager().addJob(job, page);
- }
- else {
- throw Context.reportRuntimeError("Unknown type for function.");
- }
- return id;
- }
-
- /**
- * Cancels the interval previously started using the {@link #setInterval(Object, int, Object)} method.
- * Current implementation does nothing.
- * @param intervalID specifies the interval to cancel as returned by the
- * {@link #setInterval(Object, int, Object)} method
- * @see <a href="http://msdn.microsoft.com/en-us/library/ms536353.aspx">MSDN documentation</a>
- */
- @JsxFunction
- public void clearInterval(final int intervalID) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("clearInterval(" + intervalID + ")");
- }
- getWebWindow().getJobManager().removeJob(intervalID);
- }
-
- /**
* Returns the {@code innerWidth}.
* @return the {@code innerWidth}
* @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref28.html">Mozilla doc</a>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot