Search in sources :

Example 11 with PostponedAction

use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.

the class HtmlImage method doOnLoad.

/**
 * <p><span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span></p>
 *
 * <p>Executes this element's <tt>onload</tt> or <tt>onerror</tt> handler. This method downloads the image
 * if either of these handlers are present (prior to invoking the resulting handler), because applications
 * sometimes use images to send information to the server and use these handlers to get notified when the
 * information has been received by the server.</p>
 *
 * <p>See <a href="http://www.nabble.com/How-should-we-handle-image.onload--tt9850876.html">here</a> and
 * <a href="http://www.nabble.com/Image-Onload-Support-td18895781.html">here</a> for the discussion which
 * lead up to this method.</p>
 *
 * <p>This method may be called multiple times, but will only attempt to execute the <tt>onload</tt> or
 * <tt>onerror</tt> handler the first time it is invoked.</p>
 */
public void doOnLoad() {
    if (onloadProcessed_) {
        return;
    }
    final HtmlPage htmlPage = getHtmlPageOrNull();
    if (htmlPage == null) {
        // nothing to do if embedded in XML code
        return;
    }
    final WebClient client = htmlPage.getWebClient();
    final boolean hasEventHandler = hasEventHandlers("onload") || hasEventHandlers("onerror");
    if (((hasEventHandler && client.isJavaScriptEnabled()) || client.getOptions().isDownloadImages()) && hasAttribute(SRC_ATTRIBUTE)) {
        boolean loadSuccessful = false;
        final boolean tryDownload;
        if (hasFeature(HTMLIMAGE_BLANK_SRC_AS_EMPTY)) {
            tryDownload = !StringUtils.isBlank(getSrcAttribute());
        } else {
            tryDownload = !getSrcAttribute().isEmpty();
        }
        if (tryDownload) {
            // We need to download the image and then call the resulting handler.
            try {
                downloadImageIfNeeded();
                // if the download was a success
                if (imageWebResponse_.isSuccess()) {
                    // Trigger the onload handler
                    loadSuccessful = true;
                }
            } catch (final IOException e) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("IOException while downloading image for '" + this + "' : " + e.getMessage());
                }
            }
        }
        if (!client.isJavaScriptEnabled()) {
            onloadProcessed_ = true;
            return;
        }
        if (!hasEventHandler) {
            return;
        }
        onloadProcessed_ = true;
        final Event event = new Event(this, loadSuccessful ? Event.TYPE_LOAD : Event.TYPE_ERROR);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Firing the " + event.getType() + " event for '" + this + "'.");
        }
        if (READY_STATE_LOADING.equals(htmlPage.getReadyState())) {
            final PostponedAction action = new PostponedAction(getPage(), "HtmlImage.doOnLoad") {

                @Override
                public void execute() throws Exception {
                    HtmlImage.this.fireEvent(event);
                }
            };
            htmlPage.addAfterLoadAction(action);
        } else {
            fireEvent(event);
        }
    }
}
Also used : MouseEvent(com.gargoylesoftware.htmlunit.javascript.host.event.MouseEvent) Event(com.gargoylesoftware.htmlunit.javascript.host.event.Event) PostponedAction(com.gargoylesoftware.htmlunit.javascript.PostponedAction) IOException(java.io.IOException) WebClient(com.gargoylesoftware.htmlunit.WebClient)

Example 12 with PostponedAction

use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.

the class HtmlLink method onAllChildrenAddedToPage.

/**
 * {@inheritDoc}
 */
@Override
public void onAllChildrenAddedToPage(final boolean postponed) {
    if (getOwnerDocument() instanceof XmlPage) {
        return;
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("Link node added: " + asXml());
    }
    if (!isStyleSheetLink()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Link type '" + getRelAttribute() + "' not supported (" + asXml().replaceAll("[\\r\\n]", "") + ").");
        }
        return;
    }
    final WebClient webClient = getPage().getWebClient();
    if (!webClient.getOptions().isCssEnabled()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Stylesheet Link found but ignored because css support is disabled (" + asXml().replaceAll("[\\r\\n]", "") + ").");
        }
        return;
    }
    if (!webClient.isJavaScriptEngineEnabled()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Stylesheet Link found but ignored because javascript engine is disabled (" + asXml().replaceAll("[\\r\\n]", "") + ").");
        }
        return;
    }
    final PostponedAction action = new PostponedAction(getPage(), "Loading of link " + this) {

        @Override
        public void execute() {
            final HTMLLinkElement linkElem = HtmlLink.this.getScriptableObject();
            // force loading, caching inside the link
            linkElem.getSheet();
        }
    };
    final AbstractJavaScriptEngine<?> engine = webClient.getJavaScriptEngine();
    if (postponed) {
        engine.addPostponedAction(action);
    } else {
        try {
            action.execute();
        } catch (final RuntimeException e) {
            throw e;
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }
}
Also used : HTMLLinkElement(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLLinkElement) XmlPage(com.gargoylesoftware.htmlunit.xml.XmlPage) PostponedAction(com.gargoylesoftware.htmlunit.javascript.PostponedAction) WebClient(com.gargoylesoftware.htmlunit.WebClient) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Example 13 with PostponedAction

use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.

the class HTMLDocument method scheduleImplicitClose.

private void scheduleImplicitClose() {
    if (!closePostponedAction_) {
        closePostponedAction_ = true;
        final HtmlPage page = (HtmlPage) getDomNodeOrDie();
        final WebWindow enclosingWindow = page.getEnclosingWindow();
        page.getWebClient().getJavaScriptEngine().addPostponedAction(new PostponedAction(page, "HTMLDocument.scheduleImplicitClose") {

            @Override
            public void execute() throws Exception {
                if (writeBuilder_.length() != 0) {
                    close();
                }
                closePostponedAction_ = false;
            }

            @Override
            public boolean isStillAlive() {
                return !enclosingWindow.isClosed();
            }
        });
    }
}
Also used : HtmlPage(com.gargoylesoftware.htmlunit.html.HtmlPage) PostponedAction(com.gargoylesoftware.htmlunit.javascript.PostponedAction) IOException(java.io.IOException) WebWindow(com.gargoylesoftware.htmlunit.WebWindow)

Example 14 with PostponedAction

use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.

the class ScriptElementSupport method onAllChildrenAddedToPage.

/**
 * Lifecycle method invoked after a node and all its children have been added to a page, during
 * parsing of the HTML. Intended to be overridden by nodes which need to perform custom logic
 * after they and all their child nodes have been processed by the HTML parser. This method is
 * not recursive, and the default implementation is empty, so there is no need to call
 * <tt>super.onAllChildrenAddedToPage()</tt> if you implement this method.
 * @param element the element
 * @param postponed whether to use {@link com.gargoylesoftware.htmlunit.javascript.PostponedAction} or no
 */
public static void onAllChildrenAddedToPage(final DomElement element, final boolean postponed) {
    if (element.getOwnerDocument() instanceof XmlPage) {
        return;
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("Script node added: " + element.asXml());
    }
    if (!element.getPage().getWebClient().isJavaScriptEngineEnabled()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Script found but not executed because javascript engine is disabled");
        }
        return;
    }
    final ScriptElement script = (ScriptElement) element;
    final String srcAttrib = script.getSrcAttribute();
    if (ATTRIBUTE_NOT_DEFINED != srcAttrib && script.isDeferred()) {
        return;
    }
    final WebWindow webWindow = element.getPage().getEnclosingWindow();
    if (webWindow != null) {
        final StringBuilder description = new StringBuilder().append("Execution of ").append(srcAttrib == ATTRIBUTE_NOT_DEFINED ? "inline " : "external ").append(element.getClass().getSimpleName());
        if (srcAttrib != ATTRIBUTE_NOT_DEFINED) {
            description.append(" (").append(srcAttrib).append(')');
        }
        final PostponedAction action = new PostponedAction(element.getPage(), description.toString()) {

            @Override
            public void execute() {
                // see HTMLDocument.setExecutingDynamicExternalPosponed(boolean)
                HTMLDocument jsDoc = null;
                final Window window = webWindow.getScriptableObject();
                if (window != null) {
                    jsDoc = (HTMLDocument) window.getDocument();
                    jsDoc.setExecutingDynamicExternalPosponed(element.getStartLineNumber() == -1 && ATTRIBUTE_NOT_DEFINED != srcAttrib);
                }
                try {
                    executeScriptIfNeeded(element, false, false);
                } finally {
                    if (jsDoc != null) {
                        jsDoc.setExecutingDynamicExternalPosponed(false);
                    }
                }
            }
        };
        final AbstractJavaScriptEngine<?> engine = element.getPage().getWebClient().getJavaScriptEngine();
        if (engine != null && element.hasAttribute("async") && !engine.isScriptRunning()) {
            final HtmlPage owningPage = element.getHtmlPageOrNull();
            owningPage.addAfterLoadAction(action);
        } else if (engine != null && (element.hasAttribute("async") || postponed && StringUtils.isBlank(element.getTextContent()))) {
            engine.addPostponedAction(action);
        } else {
            try {
                action.execute();
            } catch (final RuntimeException e) {
                throw e;
            } catch (final Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}
Also used : WebWindow(com.gargoylesoftware.htmlunit.WebWindow) Window(com.gargoylesoftware.htmlunit.javascript.host.Window) HTMLDocument(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument) XmlPage(com.gargoylesoftware.htmlunit.xml.XmlPage) PostponedAction(com.gargoylesoftware.htmlunit.javascript.PostponedAction) FailingHttpStatusCodeException(com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException) WebWindow(com.gargoylesoftware.htmlunit.WebWindow)

Example 15 with PostponedAction

use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.

the class MutationObserver method characterDataChanged.

/**
 * {@inheritDoc}
 */
@Override
public void characterDataChanged(final CharacterDataChangeEvent event) {
    final ScriptableObject target = event.getCharacterData().getScriptableObject();
    if (subtree_ || target == node_) {
        final MutationRecord mutationRecord = new MutationRecord();
        final Scriptable scope = getParentScope();
        mutationRecord.setParentScope(scope);
        mutationRecord.setPrototype(getPrototype(mutationRecord.getClass()));
        mutationRecord.setType("characterData");
        mutationRecord.setTarget(target);
        if (characterDataOldValue_) {
            mutationRecord.setOldValue(event.getOldValue());
        }
        final Window window = getWindow();
        final HtmlPage owningPage = (HtmlPage) window.getDocument().getPage();
        final JavaScriptEngine jsEngine = (JavaScriptEngine) window.getWebWindow().getWebClient().getJavaScriptEngine();
        jsEngine.addPostponedAction(new PostponedAction(owningPage, "MutationObserver.characterDataChanged") {

            @Override
            public void execute() throws Exception {
                final NativeArray array = new NativeArray(new Object[] { mutationRecord });
                ScriptRuntime.setBuiltinProtoAndParent(array, scope, TopLevel.Builtins.Array);
                jsEngine.callFunction(owningPage, function_, scope, MutationObserver.this, new Object[] { array });
            }
        });
    }
}
Also used : Window(com.gargoylesoftware.htmlunit.javascript.host.Window) NativeArray(net.sourceforge.htmlunit.corejs.javascript.NativeArray) ScriptableObject(net.sourceforge.htmlunit.corejs.javascript.ScriptableObject) HtmlPage(com.gargoylesoftware.htmlunit.html.HtmlPage) PostponedAction(com.gargoylesoftware.htmlunit.javascript.PostponedAction) NativeObject(net.sourceforge.htmlunit.corejs.javascript.NativeObject) ScriptableObject(net.sourceforge.htmlunit.corejs.javascript.ScriptableObject) Scriptable(net.sourceforge.htmlunit.corejs.javascript.Scriptable) HtmlUnitScriptable(com.gargoylesoftware.htmlunit.javascript.HtmlUnitScriptable) JavaScriptEngine(com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine)

Aggregations

PostponedAction (com.gargoylesoftware.htmlunit.javascript.PostponedAction)15 Page (com.gargoylesoftware.htmlunit.Page)6 SgmlPage (com.gargoylesoftware.htmlunit.SgmlPage)5 WebWindow (com.gargoylesoftware.htmlunit.WebWindow)5 HtmlPage (com.gargoylesoftware.htmlunit.html.HtmlPage)5 JavaScriptEngine (com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine)5 IOException (java.io.IOException)5 Scriptable (net.sourceforge.htmlunit.corejs.javascript.Scriptable)4 ScriptableObject (net.sourceforge.htmlunit.corejs.javascript.ScriptableObject)4 WebClient (com.gargoylesoftware.htmlunit.WebClient)3 HtmlUnitScriptable (com.gargoylesoftware.htmlunit.javascript.HtmlUnitScriptable)3 JsxFunction (com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction)3 Window (com.gargoylesoftware.htmlunit.javascript.host.Window)3 Event (com.gargoylesoftware.htmlunit.javascript.host.event.Event)3 MalformedURLException (java.net.MalformedURLException)3 ElementNotFoundException (com.gargoylesoftware.htmlunit.ElementNotFoundException)2 FailingHttpStatusCodeException (com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException)2 TopLevelWindow (com.gargoylesoftware.htmlunit.TopLevelWindow)2 HtmlElement (com.gargoylesoftware.htmlunit.html.HtmlElement)2 MessageEvent (com.gargoylesoftware.htmlunit.javascript.host.event.MessageEvent)2