All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ui4j.webkit.browser.WebKitPage Maven / Gradle / Ivy

The newest version!
package com.ui4j.webkit.browser;

import static javafx.embed.swing.SwingFXUtils.fromFXImage;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.CookieHandler;
import java.net.URLStreamHandler;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javafx.animation.AnimationTimer;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.image.WritableImage;
import javafx.scene.web.PromptData;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Callback;

import javax.imageio.ImageIO;

import com.sun.webkit.network.URLs;
import com.ui4j.api.browser.BrowserType;
import com.ui4j.api.browser.Page;
import com.ui4j.api.dialog.AlertHandler;
import com.ui4j.api.dialog.ConfirmHandler;
import com.ui4j.api.dialog.DialogEvent;
import com.ui4j.api.dialog.PromptDialogEvent;
import com.ui4j.api.dialog.PromptHandler;
import com.ui4j.api.dom.Document;
import com.ui4j.api.dom.Window;
import com.ui4j.api.event.DocumentListener;
import com.ui4j.api.event.DocumentLoadEvent;
import com.ui4j.api.util.Ui4jException;
import com.ui4j.spi.JavaScriptEngine;
import com.ui4j.spi.PageView;
import com.ui4j.webkit.WebKitIsolatedCookieHandler;
import com.ui4j.webkit.spi.WebKitJavaScriptEngine;

public class WebKitPage implements Page, PageView, JavaScriptEngine {

    private WebView webView;

    private Window window;

    private Document document;

    private Scene scene;

    private Stage stage;

    private List listeners = new ArrayList<>();

    private WebKitJavaScriptEngine engine;

    private int pageId;

    public static class AlertDelegationHandler implements EventHandler> {

        private AlertHandler handler;

        public AlertDelegationHandler(AlertHandler handler) {
            this.handler = handler;
        }

        @Override
        public void handle(WebEvent event) {
            handler.handle(new DialogEvent(event.getData()));
        }
    }

    public static class PromptDelegationHandler implements Callback {

        private PromptHandler handler;

        public PromptDelegationHandler(PromptHandler handler) {
            this.handler = handler;
        }

        @Override
        public String call(PromptData param) {
            return handler.handle(new PromptDialogEvent(param.getMessage(), param.getDefaultValue()));
        }
    }

    public static class ConfirmDelegationHandler implements Callback {

        private ConfirmHandler handler;

        public ConfirmDelegationHandler(ConfirmHandler handler) {
            this.handler = handler;
        }

        @Override
        public Boolean call(String message) {
            return handler.handle(new DialogEvent(message));
        }
    }

    public static class DocumentDelegationListener implements ChangeListener {

        private Window window;

        private DocumentListener listener;

        public DocumentDelegationListener(Window window, DocumentListener listener) {
            this.window = window;
            this.listener = listener;
        }

        @Override
        public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
            if (newState == Worker.State.SUCCEEDED) {
                DocumentLoadEvent event = new DocumentLoadEvent(window);
                listener.onLoad(event);
            }
        }

        public DocumentListener getDocumentListener() {
            return listener;
        }
    }

    public WebKitPage(WebView webView, WebKitJavaScriptEngine engine, Window window, Stage stage, Scene scene, Document document, int pageId) {
        this.webView = webView;
        this.window = window;
        this.document = document;
        this.engine = engine;
        this.pageId = pageId;
        this.stage = stage;
        this.scene = scene;
    }

    @Override
    public void show(boolean maximized) {
        stage.setMaximized(maximized);
        stage.centerOnScreen();
        stage.toFront();
        stage.show();
    }

    @Override
    public void show() {
        show(false);
    }

    @Override
    public void addDocumentListener(DocumentListener listener) {
        WebEngine engine = webView.getEngine();
        DocumentDelegationListener delegationListener = new DocumentDelegationListener(window, listener);
        listeners.add(delegationListener);
        engine.getLoadWorker().stateProperty().addListener(delegationListener);
    }

    @Override
    public void removeListener(DocumentListener listener) {
        for (DocumentDelegationListener delegation : listeners) {
            if (delegation.getDocumentListener().equals(listener)) {
                WebEngine engine = webView.getEngine();
                engine.getLoadWorker().stateProperty().removeListener(delegation);
            }
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public void close() {
        // HACK #26
        Field handlerMap;
        try {
            handlerMap = URLs.class.getDeclaredField("handlerMap");
            handlerMap.setAccessible(true);
            Map handlers = (Map) handlerMap.get(null);
            handlers.remove("ui4j-" + String.valueOf(pageId));
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            throw new Ui4jException(e);
        }
        CookieHandler cookieHandler = CookieHandler.getDefault();
        if (cookieHandler != null
                        && cookieHandler instanceof WebKitIsolatedCookieHandler) {
            WebKitIsolatedCookieHandler whandler = (WebKitIsolatedCookieHandler) cookieHandler;
            whandler.remove(getWebView());
        }
        // HACK #26
        if (getStage() != null) {
            getStage().close();
        }
    }

    public WebView getWebView() {
        return webView;
    }

    @Override
    public Document getDocument() {
        return document;
    }

    @Override
    public Window getWindow() {
        return window;
    }

    public Scene getScene() {
        return scene;
    }

    public Stage getStage() {
        return stage;
    }

    @Override
    public void hide() {
        if (stage != null) {
            stage.hide();
        }
    }

    @Override
    public Object executeScript(String script) {
        Object result = engine.executeScript(script);
        return result;
    }

    @Override
    public WebView getView() {
        return webView;
    }

    @Override
    public WebEngine getEngine() {
        return engine.getEngine();
    }

    @Override
    public BrowserType getBrowserType() {
        return BrowserType.WebKit;
    }

    public String getDocumentState() {
        return String.valueOf(webView.getEngine().executeScript("document.readyState"));
    }

    public int getPageId() {
        return pageId;
    }

    @Override
    public void captureScreen(OutputStream os) {
        final AnimationTimer timer = new AnimationTimer() {

            private int pulseCounter;

            @Override
            public void handle(long now) {
                pulseCounter += 1;
                if (pulseCounter > 2) {
                    stop();
                    WebView view = (WebView) getView();
                    WritableImage snapshot = view.snapshot(new SnapshotParameters(), null);
                    BufferedImage image = fromFXImage(snapshot, null);
                    try (OutputStream stream = os) {
                        ImageIO.write(image, "png", stream);
                    } catch (IOException e) {
                        throw new Ui4jException(e);
                    }
                }
            }
        };

        timer.start();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy