use of net.sourceforge.htmlunit.corejs.javascript.ContextAction in project htmlunit by HtmlUnit.
the class XMLHTTPRequest method send.
/**
* Sends an HTTP request to the server and receives a response.
* @param body the body of the message being sent with the request.
*/
@JsxFunction
public void send(final Object body) {
if (webRequest_ == null) {
setState(STATE_DONE, Context.getCurrentContext());
return;
}
if (sent_) {
throw Context.reportRuntimeError("Unspecified error (request already sent).");
}
sent_ = true;
prepareRequest(body);
// quite strange but IE seems to fire state loading twice
setState(STATE_OPENED, Context.getCurrentContext());
final Window w = getWindow();
final WebClient client = w.getWebWindow().getWebClient();
final AjaxController ajaxController = client.getAjaxController();
final HtmlPage page = (HtmlPage) w.getWebWindow().getEnclosedPage();
final boolean synchron = ajaxController.processSynchron(page, webRequest_, async_);
if (synchron) {
doSend(Context.getCurrentContext());
} else {
// Create and start a thread in which to execute the request.
final ContextFactory cf = ((JavaScriptEngine) client.getJavaScriptEngine()).getContextFactory();
final ContextAction<Object> action = cx -> {
// KEY_STARTING_SCOPE maintains a stack of scopes
@SuppressWarnings("unchecked") Deque<Scriptable> stack = (Deque<Scriptable>) cx.getThreadLocal(JavaScriptEngine.KEY_STARTING_SCOPE);
if (null == stack) {
stack = new ArrayDeque<>();
cx.putThreadLocal(JavaScriptEngine.KEY_STARTING_SCOPE, stack);
}
stack.push(w);
try {
doSend(cx);
} finally {
stack.pop();
}
return null;
};
final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().createJavascriptXMLHttpRequestJob(cf, action);
if (LOG.isDebugEnabled()) {
LOG.debug("Starting XMLHTTPRequest thread for asynchronous request");
}
jobID_ = w.getWebWindow().getJobManager().addJob(job, page);
}
}
use of net.sourceforge.htmlunit.corejs.javascript.ContextAction in project htmlunit by HtmlUnit.
the class HTMLCollectionFrames method postMessage.
/**
* Posts a message.
* @param message the object passed to the window
* @param targetOrigin the origin this window must be for the event to be dispatched
* @param transfer an optional sequence of Transferable objects
* @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage">MDN documentation</a>
*/
@JsxFunction
public void postMessage(final String message, final String targetOrigin, final Object transfer) {
final WebWindow webWindow = getWebWindow();
final Page page = webWindow.getEnclosedPage();
final URL currentURL = page.getUrl();
if (!"*".equals(targetOrigin) && !"/".equals(targetOrigin)) {
final URL targetURL;
try {
targetURL = new URL(targetOrigin);
} catch (final Exception e) {
throw Context.throwAsScriptRuntimeEx(new Exception("SyntaxError: Failed to execute 'postMessage' on 'Window': Invalid target origin '" + targetOrigin + "' was specified (reason: " + e.getMessage() + "."));
}
if (getPort(targetURL) != getPort(currentURL)) {
return;
}
if (!targetURL.getHost().equals(currentURL.getHost())) {
return;
}
if (!targetURL.getProtocol().equals(currentURL.getProtocol())) {
return;
}
}
final MessageEvent event = new MessageEvent();
final String origin = currentURL.getProtocol() + "://" + currentURL.getHost() + ':' + currentURL.getPort();
event.initMessageEvent(Event.TYPE_MESSAGE, false, false, message, origin, "", this, transfer);
event.setParentScope(this);
event.setPrototype(getPrototype(event.getClass()));
final JavaScriptEngine jsEngine = (JavaScriptEngine) webWindow.getWebClient().getJavaScriptEngine();
final PostponedAction action = new PostponedAction(page, "Window.postMessage") {
@Override
public void execute() throws Exception {
final ContextAction<Object> contextAction = cx -> dispatchEvent(event);
final ContextFactory cf = jsEngine.getContextFactory();
cf.call(contextAction);
}
};
jsEngine.addPostponedAction(action);
}
use of net.sourceforge.htmlunit.corejs.javascript.ContextAction in project htmlunit by HtmlUnit.
the class WorkerJob method postMessage.
/**
* Posts a message to the {@link Worker} in the page's context.
* @param message the message
*/
@JsxFunction
public void postMessage(final Object message) {
final MessageEvent event = new MessageEvent();
event.initMessageEvent(Event.TYPE_MESSAGE, false, false, message, origin_, "", owningWindow_, Undefined.instance);
event.setParentScope(owningWindow_);
event.setPrototype(owningWindow_.getPrototype(event.getClass()));
if (LOG.isDebugEnabled()) {
LOG.debug("[DedicatedWorker] postMessage: {}" + message);
}
final JavaScriptEngine jsEngine = (JavaScriptEngine) owningWindow_.getWebWindow().getWebClient().getJavaScriptEngine();
final ContextAction<Object> action = cx -> {
worker_.getEventListenersContainer().executeCapturingListeners(event, null);
final Object[] args = { event };
worker_.getEventListenersContainer().executeBubblingListeners(event, args);
return null;
};
final ContextFactory cf = jsEngine.getContextFactory();
final JavaScriptJob job = new WorkerJob(cf, action, "postMessage: " + Context.toString(message));
final HtmlPage page = (HtmlPage) owningWindow_.getDocument().getPage();
owningWindow_.getWebWindow().getJobManager().addJob(job, page);
}
use of net.sourceforge.htmlunit.corejs.javascript.ContextAction in project htmlunit by HtmlUnit.
the class WorkerJob method messagePosted.
void messagePosted(final Object message) {
final MessageEvent event = new MessageEvent();
event.initMessageEvent(Event.TYPE_MESSAGE, false, false, message, origin_, "", owningWindow_, Undefined.instance);
event.setParentScope(owningWindow_);
event.setPrototype(owningWindow_.getPrototype(event.getClass()));
final JavaScriptEngine jsEngine = (JavaScriptEngine) owningWindow_.getWebWindow().getWebClient().getJavaScriptEngine();
final ContextAction<Object> action = cx -> {
executeEvent(cx, event);
return null;
};
final ContextFactory cf = jsEngine.getContextFactory();
final JavaScriptJob job = new WorkerJob(cf, action, "messagePosted: " + Context.toString(message));
final HtmlPage page = (HtmlPage) owningWindow_.getDocument().getPage();
owningWindow_.getWebWindow().getJobManager().addJob(job, page);
}
use of net.sourceforge.htmlunit.corejs.javascript.ContextAction in project htmlunit by HtmlUnit.
the class DebuggingWebConnection method uncompressJavaScript.
/**
* Tries to uncompress the JavaScript code in the provided response.
* @param response the response to uncompress
* @return a new response with uncompressed JavaScript code or the original response in case of failure
*/
protected WebResponse uncompressJavaScript(final WebResponse response) {
final WebRequest request = response.getWebRequest();
final String scriptName = request.getUrl().toString();
final String scriptSource = response.getContentAsString();
// skip if it is already formatted? => TODO
final ContextFactory factory = new ContextFactory();
final ContextAction<Object> action = cx -> {
cx.setOptimizationLevel(-1);
final Script script = cx.compileString(scriptSource, scriptName, 0, null);
return cx.decompileScript(script, 4);
};
try {
final String decompileScript = (String) factory.call(action);
final List<NameValuePair> responseHeaders = new ArrayList<>(response.getResponseHeaders());
for (int i = responseHeaders.size() - 1; i >= 0; i--) {
if ("content-encoding".equalsIgnoreCase(responseHeaders.get(i).getName())) {
responseHeaders.remove(i);
}
}
final WebResponseData wrd = new WebResponseData(decompileScript.getBytes(), response.getStatusCode(), response.getStatusMessage(), responseHeaders);
return new WebResponse(wrd, response.getWebRequest().getUrl(), response.getWebRequest().getHttpMethod(), response.getLoadTime());
} catch (final Exception e) {
LOG.warn("Failed to decompress JavaScript response. Delivering as it.", e);
}
return response;
}
Aggregations