use of com.gargoylesoftware.htmlunit.ScriptResult in project htmlunit by HtmlUnit.
the class EventListenersContainer method executeEventListeners.
private void executeEventListeners(final int eventPhase, final Event event, final Object[] args) {
final DomNode node = jsNode_.getDomNodeOrNull();
// some event don't apply on all kind of nodes, for instance "blur"
if (node != null && !node.handles(event)) {
return;
}
final TypeContainer container = getTypeContainer(event.getType());
final List<Scriptable> listeners = container.getListeners(eventPhase);
if (!listeners.isEmpty()) {
event.setCurrentTarget(jsNode_);
final HtmlPage page;
if (jsNode_ instanceof Window) {
page = (HtmlPage) jsNode_.getDomNodeOrDie();
} else {
final Scriptable parentScope = jsNode_.getParentScope();
if (parentScope instanceof Window) {
page = (HtmlPage) ((Window) parentScope).getDomNodeOrDie();
} else if (parentScope instanceof HTMLDocument) {
page = ((HTMLDocument) parentScope).getPage();
} else {
page = ((HTMLElement) parentScope).getDomNodeOrDie().getHtmlPageOrNull();
}
}
// no need for a copy, listeners are copy on write
for (Scriptable listener : listeners) {
boolean isPropertyHandler = false;
if (listener == TypeContainer.EVENT_HANDLER_PLACEHOLDER) {
listener = container.handler_;
isPropertyHandler = true;
}
Function function = null;
Scriptable thisObject = null;
if (listener instanceof Function) {
function = (Function) listener;
thisObject = jsNode_;
} else if (listener instanceof NativeObject) {
final Object handleEvent = ScriptableObject.getProperty(listener, "handleEvent");
if (handleEvent instanceof Function) {
function = (Function) handleEvent;
thisObject = listener;
}
}
if (function != null) {
final ScriptResult result = page.executeJavaScriptFunction(function, thisObject, args, node);
// Return value is only honored for property handlers (Tested in Chrome/FF/IE11)
if (isPropertyHandler && !ScriptResult.isUndefined(result)) {
event.handlePropertyHandlerReturnValue(result.getJavaScriptResult());
}
}
if (event.isImmediatePropagationStopped()) {
return;
}
}
}
}
use of com.gargoylesoftware.htmlunit.ScriptResult in project htmlunit by HtmlUnit.
the class HTMLDocument method dispatchEvent.
/**
* Dispatches an event into the event system (standards-conformant browsers only). See
* <a href="https://developer.mozilla.org/en-US/docs/DOM/element.dispatchEvent">the Gecko
* DOM reference</a> for more information.
*
* @param event the event to be dispatched
* @return {@code false} if at least one of the event handlers which handled the event
* called <tt>preventDefault</tt>; {@code true} otherwise
*/
@Override
@JsxFunction
public boolean dispatchEvent(final Event event) {
event.setTarget(this);
final ScriptResult result = fireEvent(event);
return !event.isAborted(result);
}
use of com.gargoylesoftware.htmlunit.ScriptResult in project htmlunit by HtmlUnit.
the class NamedAttrNodeMapImpl method fireEvent.
/**
* <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
*
* Fires the event on the element. Nothing is done if JavaScript is disabled.
* @param event the event to fire
* @return the execution result, or {@code null} if nothing is executed
*/
public ScriptResult fireEvent(final Event event) {
final WebClient client = getPage().getWebClient();
if (!client.isJavaScriptEnabled()) {
return null;
}
if (!handles(event)) {
return null;
}
if (LOG.isDebugEnabled()) {
LOG.debug("Firing " + event);
}
final EventTarget jsElt = getScriptableObject();
final HtmlUnitContextFactory cf = ((JavaScriptEngine) client.getJavaScriptEngine()).getContextFactory();
final ScriptResult result = cf.callSecured(cx -> jsElt.fireEvent(event), getHtmlPageOrNull());
if (event.isAborted(result)) {
preventDefault();
}
return result;
}
use of com.gargoylesoftware.htmlunit.ScriptResult in project htmlunit by HtmlUnit.
the class NamedAttrNodeMapImpl method dblClick.
/**
* Simulates double-clicking on this element, returning the page in the window that has the focus
* after the element has been clicked. Note that the returned page may or may not be the same
* as the original page, depending on the type of element being clicked, the presence of JavaScript
* action listeners, etc. Note also that {@link #click(boolean, boolean, boolean)} is automatically
* called first.
*
* @param shiftKey {@code true} if SHIFT is pressed during the double-click
* @param ctrlKey {@code true} if CTRL is pressed during the double-click
* @param altKey {@code true} if ALT is pressed during the double-click
* @param <P> the page type
* @return the page that occupies this element's window after the element has been double-clicked
* @exception IOException if an IO error occurs
*/
@SuppressWarnings("unchecked")
public <P extends Page> P dblClick(final boolean shiftKey, final boolean ctrlKey, final boolean altKey) throws IOException {
if (isDisabledElementAndDisabled()) {
return (P) getPage();
}
// call click event first
P clickPage = click(shiftKey, ctrlKey, altKey);
if (clickPage != getPage()) {
if (LOG.isDebugEnabled()) {
LOG.debug("dblClick() is ignored, as click() loaded a different page.");
}
return clickPage;
}
// call click event a second time
clickPage = click(shiftKey, ctrlKey, altKey);
if (clickPage != getPage()) {
if (LOG.isDebugEnabled()) {
LOG.debug("dblClick() is ignored, as click() loaded a different page.");
}
return clickPage;
}
final Event event;
final WebClient webClient = getPage().getWebClient();
if (webClient.getBrowserVersion().hasFeature(EVENT_ONDOUBLECLICK_USES_POINTEREVENT)) {
event = new PointerEvent(this, MouseEvent.TYPE_DBL_CLICK, shiftKey, ctrlKey, altKey, MouseEvent.BUTTON_LEFT, 0);
} else {
event = new MouseEvent(this, MouseEvent.TYPE_DBL_CLICK, shiftKey, ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
}
final ScriptResult scriptResult = fireEvent(event);
if (scriptResult == null) {
return clickPage;
}
return (P) webClient.getCurrentWindow().getEnclosedPage();
}
use of com.gargoylesoftware.htmlunit.ScriptResult in project htmlunit by HtmlUnit.
the class HTMLCollectionFrames method dispatchEvent.
/**
* {@inheritDoc}
*/
@Override
public boolean dispatchEvent(final Event event) {
event.setTarget(this);
final ScriptResult result = fireEvent(event);
return !event.isAborted(result);
}
Aggregations