package com.sun.webkit;
import javafx.application.ConditionalFeature;
import javafx.application.Platform;
import com.sun.glass.utils.NativeLibLoader;
import com.sun.javafx.logging.PlatformLogger;
import com.sun.javafx.logging.PlatformLogger.Level;
import com.sun.webkit.event.WCFocusEvent;
import com.sun.webkit.event.WCInputMethodEvent;
import com.sun.webkit.event.WCKeyEvent;
import com.sun.webkit.event.WCMouseEvent;
import com.sun.webkit.event.WCMouseWheelEvent;
import com.sun.webkit.graphics.*;
import com.sun.webkit.network.CookieManager;
import static com.sun.webkit.network.URLs.newURL;
import java.net.CookieHandler;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;
import netscape.javascript.JSException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public final class WebPage {
private final static PlatformLogger log = PlatformLogger.getLogger(WebPage.class.getName());
private final static PlatformLogger paintLog = PlatformLogger.getLogger(WebPage.class.getName() + ".paint");
private static final int MAX_FRAME_QUEUE_SIZE = 10;
private long pPage = 0;
private boolean isDisposed = false;
private int width, height;
private int fontSmoothingType;
private final WCFrameView hostWindow;
private final Set<Long> frames = new HashSet<Long>();
private final AccessControlContext accessControlContext;
private final Map<Integer, String> requestURLs =
new HashMap<Integer, String>();
private final Set<Integer> requestStarted = new HashSet<Integer>();
private static final ReentrantLock PAGE_LOCK = new ReentrantLock();
private final Queue<RenderFrame> frameQueue = new LinkedList<RenderFrame>();
private RenderFrame currentFrame = new RenderFrame();
private int updateContentCycleID;
static {
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
NativeLibLoader.loadLibrary("jfxwebkit");
log.finer("jfxwebkit loaded");
if (CookieHandler.getDefault() == null) {
boolean setDefault = Boolean.valueOf(System.getProperty(
"com.sun.webkit.setDefaultCookieHandler",
"true"));
if (setDefault) {
CookieHandler.setDefault(new CookieManager());
}
}
final boolean useJIT = Boolean.valueOf(System.getProperty(
"com.sun.webkit.useJIT", "true"));
final boolean useDFGJIT = Boolean.valueOf(System.getProperty(
"com.sun.webkit.useDFGJIT", "true"));
boolean useCSS3D = Boolean.valueOf(System.getProperty(
"com.sun.webkit.useCSS3D", "false"));
useCSS3D = useCSS3D && Platform.isSupported(ConditionalFeature.SCENE3D);
twkInitWebCore(useJIT, useDFGJIT, useCSS3D);
return null;
});
}
private static boolean firstWebPageCreated = false;
private static void collectJSCGarbages() {
Invoker.getInvoker().checkEventThread();
Disposer.addRecord(new Object(), WebPage::collectJSCGarbages);
twkDoJSCGarbageCollection();
}
public WebPage(WebPageClient pageClient,
UIClient uiClient,
PolicyClient policyClient,
InspectorClient inspectorClient,
ThemeClient themeClient,
boolean editable)
{
Invoker.getInvoker().checkEventThread();
this.pageClient = pageClient;
this.uiClient = uiClient;
this.policyClient = policyClient;
this.inspectorClient = inspectorClient;
if (themeClient != null) {
this.renderTheme = themeClient.createRenderTheme();
this.scrollbarTheme = themeClient.createScrollBarTheme();
} else {
this.renderTheme = null;
this.scrollbarTheme = null;
}
accessControlContext = AccessController.getContext();
hostWindow = new WCFrameView(this);
pPage = twkCreatePage(editable);
twkInit(pPage, false, WCGraphicsManager.getGraphicsManager().getDevicePixelScale());
if (pageClient != null && pageClient.isBackBufferSupported()) {
backbuffer = pageClient.createBackBuffer();
backbuffer.ref();
}
if (!firstWebPageCreated) {
Disposer.addRecord(new Object(), WebPage::collectJSCGarbages);
firstWebPageCreated = true;
}
}
long getPage() {
return pPage;
}
private WCWidget getHostWindow() {
return hostWindow;
}
public AccessControlContext getAccessControlContext() {
return accessControlContext;
}
static boolean lockPage() {
return Invoker.getInvoker().lock(PAGE_LOCK);
}
static boolean unlockPage() {
return Invoker.getInvoker().unlock(PAGE_LOCK);
}
private WCPageBackBuffer backbuffer;
private List<WCRectangle> dirtyRects = new LinkedList<WCRectangle>();
private void addDirtyRect(WCRectangle toPaint) {
if (toPaint.getWidth() <= 0 || toPaint.getHeight() <= 0) {
return;
}
for (Iterator<WCRectangle> it = dirtyRects.iterator(); it.hasNext();) {
WCRectangle rect = it.next();
if (rect.contains(toPaint)) {
return;
}
if (toPaint.contains(rect)) {
it.remove();
continue;
}
WCRectangle u = rect.createUnion(toPaint);
if (u.getIntWidth() * u.getIntHeight() <
rect.getIntWidth() * rect.getIntHeight() +
toPaint.getIntWidth() * toPaint.getIntHeight())
{
it.remove();
toPaint = u;
continue;
}
}
dirtyRects.add(toPaint);
}
public boolean isDirty() {
lockPage();
try {
return !dirtyRects.isEmpty();
} finally {
unlockPage();
}
}
private void updateDirty(WCRectangle clip) {
if (paintLog.isLoggable(Level.FINEST)) {
paintLog.finest("Entering, dirtyRects: {0}, currentFrame: {1}",
new Object[] {dirtyRects, currentFrame});
}
if (isDisposed || width <= 0 || height <= 0) {
dirtyRects.clear();
return;
}
if (clip == null) {
clip = new WCRectangle(0, 0, width, height);
}
List<WCRectangle> oldDirtyRects = dirtyRects;
dirtyRects = new LinkedList<WCRectangle>();
twkPrePaint(getPage());
while (!oldDirtyRects.isEmpty()) {
WCRectangle r = oldDirtyRects.remove(0).intersection(clip);
if (r.getWidth() <= 0 || r.getHeight() <= 0) {
continue;
}
paintLog.finest("Updating: {0}", r);
WCRenderQueue rq = WCGraphicsManager.getGraphicsManager()
.createRenderQueue(r, true);
twkUpdateContent(getPage(), rq, r.getIntX() - 1, r.getIntY() - 1,
r.getIntWidth() + 2, r.getIntHeight() + 2);
currentFrame.addRenderQueue(rq);
}
{
WCRenderQueue rq = WCGraphicsManager.getGraphicsManager()
.createRenderQueue(clip, false);
twkPostPaint(getPage(), rq,
clip.getIntX(), clip.getIntY(),
clip.getIntWidth(), clip.getIntHeight());
currentFrame.addRenderQueue(rq);
}
if (paintLog.isLoggable(Level.FINEST)) {
paintLog.finest("Dirty rects processed, dirtyRects: {0}, currentFrame: {1}",
new Object[] {dirtyRects, currentFrame});
}
if (currentFrame.getRQList().size() > 0) {
synchronized (frameQueue) {
paintLog.finest("About to update frame queue, frameQueue: {0}", frameQueue);
Iterator<RenderFrame> it = frameQueue.iterator();
while (it.hasNext()) {
RenderFrame frame = it.next();
for (WCRenderQueue rq : currentFrame.getRQList()) {
WCRectangle rqRect = rq.getClip();
if (rq.isOpaque()
&& rqRect.contains(frame.getEnclosingRect()))
{
paintLog.finest("Dropping: {0}", frame);
frame.drop();
it.remove();
break;
}
}
}
frameQueue.add(currentFrame);
currentFrame = new RenderFrame();
if (frameQueue.size() > MAX_FRAME_QUEUE_SIZE) {
paintLog.finest("Frame queue exceeded maximum "
+ "size, clearing and requesting full repaint");
dropRenderFrames();
repaintAll();
}
paintLog.finest("Frame queue updated, frameQueue: {0}", frameQueue);
}
}
if (paintLog.isLoggable(Level.FINEST)) {
paintLog.finest("Exiting, dirtyRects: {0}, currentFrame: {1}",
new Object[] {dirtyRects, currentFrame});
}
}
private void scroll(int x, int y, int w, int h, int dx, int dy) {
if (paintLog.isLoggable(Level.FINEST)) {
paintLog.finest("rect=[" + x + ", " + y + " " + w + "x" + h +
"] delta=[" + dx + ", " + dy + "]");
}
dx += currentFrame.scrollDx;
dy += currentFrame.scrollDy;
if (Math.abs(dx) < w && Math.abs(dy) < h) {
int cx = (dx >= 0) ? x : x - dx;
int cy = (dy >= 0) ? y : y - dy;
int cw = (dx == 0) ? w : w - Math.abs(dx);
int ch = (dy == 0) ? h : h - Math.abs(dy);
WCRenderQueue rq = WCGraphicsManager.getGraphicsManager()
.createRenderQueue(
new WCRectangle(0, 0, width, height), false);
ByteBuffer buffer = ByteBuffer.allocate(32)
.order(ByteOrder.nativeOrder())
.putInt(GraphicsDecoder.COPYREGION)
.putInt(backbuffer.getID())
.putInt(cx).putInt(cy).putInt(cw).putInt(ch)
.putInt(dx).putInt(dy);
buffer.flip();
rq.addBuffer(buffer);
currentFrame.drop();
currentFrame.addRenderQueue(rq);
currentFrame.scrollDx = dx;
currentFrame.scrollDy = dy;
if (!dirtyRects.isEmpty()) {
WCRectangle scrollRect = new WCRectangle(x, y, w, h);
for (WCRectangle r: dirtyRects) {
if (scrollRect.contains(r)) {
if (paintLog.isLoggable(Level.FINEST)) {
paintLog.finest("translating old dirty rect by the delta: " + r);
}
r.translate(dx, dy);
}
}
}
}
addDirtyRect(new WCRectangle(x, dy >= 0 ? y : y + h + dy,
w, Math.abs(dy)));
addDirtyRect(new WCRectangle(dx >= 0 ? x : x + w + dx, y,
Math.abs(dx), h - Math.abs(dy)));
}
private static final class RenderFrame {
private final List<WCRenderQueue> rqList =
new LinkedList<WCRenderQueue>();
private int scrollDx, scrollDy;
private final WCRectangle enclosingRect = new WCRectangle();
private void addRenderQueue(WCRenderQueue rq) {
if (rq.isEmpty()) {
return;
}
rqList.add(rq);
WCRectangle rqRect = rq.getClip();
if (enclosingRect.isEmpty()) {
enclosingRect.setFrame(rqRect.getX(), rqRect.getY(),
rqRect.getWidth(), rqRect.getHeight());
} else if (rqRect.isEmpty()) {
} else {
WCRectangle.union(enclosingRect, rqRect, enclosingRect);
}
}
private List<WCRenderQueue> getRQList() {
return rqList;
}
private WCRectangle getEnclosingRect() {
return enclosingRect;
}
private void drop() {
for (WCRenderQueue rq : rqList) {
rq.dispose();
}
rqList.clear();
enclosingRect.setFrame(0, 0, 0, 0);
scrollDx = 0;
scrollDy = 0;
}
@Override
public String toString() {
return "RenderFrame{"
+ "rqList=" + rqList + ", "
+ "enclosingRect=" + enclosingRect
+ "}";
}
}
private final WebPageClient pageClient;
private final UIClient uiClient;
private final PolicyClient policyClient;
private InputMethodClient imClient;
private final List<LoadListenerClient> loadListenerClients =
new LinkedList<LoadListenerClient>();
private final InspectorClient inspectorClient;
private final RenderTheme renderTheme;
private final ScrollBarTheme scrollbarTheme;
public WebPageClient getPageClient() {
return pageClient;
}
public void setInputMethodClient(InputMethodClient imClient) {
this.imClient = imClient;
}
public void setInputMethodState(boolean state) {
if (imClient != null) {
imClient.activateInputMethods(state);
}
}
public void addLoadListenerClient(LoadListenerClient l) {
if (!loadListenerClients.contains(l)) {
loadListenerClients.add(l);
}
}
private RenderTheme getRenderTheme() {
return renderTheme;
}
private static RenderTheme fwkGetDefaultRenderTheme() {
return ThemeClient.getDefaultRenderTheme();
}
private ScrollBarTheme getScrollBarTheme() {
return scrollbarTheme;
}
public void setBounds(int x, int y, int w, int h) {
lockPage();
try {
log.fine("setBounds: " + x + " " + y + " " + w + " " + h);
if (isDisposed) {
log.fine("setBounds() request for a disposed web page.");
return;
}
width = w;
height = h;
twkSetBounds(getPage(), 0, 0, w, h);
repaintAll();
} finally {
unlockPage();
}
}
public void setOpaque(long frameID, boolean isOpaque) {
lockPage();
try {
log.fine("setOpaque: " + isOpaque);
if (isDisposed) {
log.fine("setOpaque() request for a disposed web page.");
return;
}
if (!frames.contains(frameID)) {
return;
}
twkSetTransparent(frameID, !isOpaque);
} finally {
unlockPage();
}
}
public void setBackgroundColor(long frameID, int backgroundColor) {
lockPage();
try {
log.fine("setBackgroundColor: " + backgroundColor);
if (isDisposed) {
log.fine("setBackgroundColor() request for a disposed web page.");
return;
}
if (!frames.contains(frameID)) {
return;
}
twkSetBackgroundColor(frameID, backgroundColor);
} finally {
unlockPage();
}
}
public void setBackgroundColor(int backgroundColor) {
lockPage();
try {
log.fine("setBackgroundColor: " + backgroundColor +
" for all frames");
if (isDisposed) {
log.fine("setBackgroundColor() request for a disposed web page.");
return;
}
for (long frameID: frames) {
twkSetBackgroundColor(frameID, backgroundColor);
}
} finally {
unlockPage();
}
}
public void updateContent(WCRectangle toPaint) {
lockPage();
try {
++updateContentCycleID;
paintLog.finest("toPaint: {0}", toPaint);
if (isDisposed) {
paintLog.fine("updateContent() request for a disposed web page.");
return;
}
updateDirty(toPaint);
} finally {
unlockPage();
}
}
public int getUpdateContentCycleID() {
return updateContentCycleID;
}
public boolean isRepaintPending() {
lockPage();
try {
synchronized (frameQueue) {
return !frameQueue.isEmpty();
}
} finally {
unlockPage();
}
}
public void print(WCGraphicsContext gc,
final int x, final int y, final int w, final int h)
{
lockPage();
try {
final WCRenderQueue rq = WCGraphicsManager.getGraphicsManager().
createRenderQueue(new WCRectangle(x, y, w, h), true);
FutureTask<Void> f = new FutureTask<Void>(() -> {
twkUpdateContent(getPage(), rq, x, y, w, h);
}, null);
Invoker.getInvoker().invokeOnEventThread(f);
try {
f.get();
} catch (ExecutionException ex) {
throw new AssertionError(ex);
} catch (InterruptedException ex) {
}
rq.decode(gc);
} finally {
unlockPage();
}
}
public void paint(WCGraphicsContext gc, int x, int y, int w, int h) {
lockPage();
try {
if (pageClient != null && pageClient.isBackBufferSupported()) {
if (!backbuffer.validate(width, height)) {
Invoker.getInvoker().invokeOnEventThread(() -> {
repaintAll();
});
return;
}
WCGraphicsContext bgc = backbuffer.createGraphics();
try {
paint2GC(bgc);
bgc.flush();
} finally {
backbuffer.disposeGraphics(bgc);
}
backbuffer.flush(gc, x, y, w, h);
} else {
paint2GC(gc);
}
} finally {
unlockPage();
}
}
private void paint2GC(WCGraphicsContext gc) {
paintLog.finest("Entering");
gc.setFontSmoothingType(this.fontSmoothingType);
List<RenderFrame> framesToRender;
synchronized (frameQueue) {
framesToRender = new ArrayList(frameQueue);
frameQueue.clear();
}
paintLog.finest("Frames to render: {0}", framesToRender);
for (RenderFrame frame : framesToRender) {
paintLog.finest("Rendering: {0}", frame);
for (WCRenderQueue rq : frame.getRQList()) {
gc.saveState();
if (rq.getClip() != null) {
gc.setClip(rq.getClip());
}
rq.decode(gc);
gc.restoreState();
}
}
paintLog.finest("Exiting");
}
public void dropRenderFrames() {
lockPage();
try {
currentFrame.drop();
synchronized (frameQueue) {
for (RenderFrame frame = frameQueue.poll(); frame != null; frame = frameQueue.poll()) {
frame.drop();
}
}
} finally {
unlockPage();
}
}
public void dispatchFocusEvent(WCFocusEvent fe) {
lockPage();
try {
log.finest("dispatchFocusEvent: " + fe);
if (isDisposed) {
log.fine("Focus event for a disposed web page.");
return;
}
twkProcessFocusEvent(getPage(), fe.getID(), fe.getDirection());
} finally {
unlockPage();
}
}
public boolean dispatchKeyEvent(WCKeyEvent ke) {
lockPage();
try {
log.finest("dispatchKeyEvent: " + ke);
if (isDisposed) {
log.fine("Key event for a disposed web page.");
return false;
}
if (WCKeyEvent.filterEvent(ke)) {
log.finest("filtered");
return false;
}
return twkProcessKeyEvent(getPage(), ke.getType(), ke.getText(),
ke.getKeyIdentifier(),
ke.getWindowsVirtualKeyCode(),
ke.isShiftDown(), ke.isCtrlDown(),
ke.isAltDown(), ke.isMetaDown(), ke.getWhen() / 1000.0);
} finally {
unlockPage();
}
}
public boolean dispatchMouseEvent(WCMouseEvent me) {
lockPage();
try {
log.finest("dispatchMouseEvent: " + me.getX() + "," + me.getY());
if (isDisposed) {
log.fine("Mouse event for a disposed web page.");
return false;
}
return !isDragConfirmed()
&& twkProcessMouseEvent(getPage(), me.getID(),
me.getButton(), me.getClickCount(),
me.getX(), me.getY(), me.getScreenX(), me.getScreenY(),
me.isShiftDown(), me.isControlDown(), me.isAltDown(), me.isMetaDown(), me.isPopupTrigger(),
me.getWhen() / 1000.0);
} finally {
unlockPage();
}
}
public boolean dispatchMouseWheelEvent(WCMouseWheelEvent me) {
lockPage();
try {
log.finest("dispatchMouseWheelEvent: " + me);
if (isDisposed) {
log.fine("MouseWheel event for a disposed web page.");
return false;
}
return twkProcessMouseWheelEvent(getPage(),
me.getX(), me.getY(), me.getScreenX(), me.getScreenY(),
me.getDeltaX(), me.getDeltaY(),
me.isShiftDown(), me.isControlDown(), me.isAltDown(), me.isMetaDown(),
me.getWhen() / 1000.0);
} finally {
unlockPage();
}
}
public boolean dispatchInputMethodEvent(WCInputMethodEvent ie) {
lockPage();
try {
log.finest("dispatchInputMethodEvent: " + ie);
if (isDisposed) {
log.fine("InputMethod event for a disposed web page.");
return false;
}
switch (ie.getID()) {
case WCInputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
return twkProcessInputTextChange(getPage(),
ie.getComposed(), ie.getCommitted(),
ie.getAttributes(), ie.getCaretPosition());
case WCInputMethodEvent.CARET_POSITION_CHANGED:
return twkProcessCaretPositionChange(getPage(),
ie.getCaretPosition());
}
return false;
} finally {
unlockPage();
}
}
public final static int DND_DST_ENTER = 0;
public final static int DND_DST_OVER = 1;
public final static int DND_DST_CHANGE = 2;
public final static int DND_DST_EXIT = 3;
public final static int DND_DST_DROP = 4;
public final static int DND_SRC_ENTER = 100;
public final static int DND_SRC_OVER = 101;
public final static int DND_SRC_CHANGE = 102;
public final static int DND_SRC_EXIT = 103;
public final static int DND_SRC_DROP = 104;
public int dispatchDragOperation(
int commandId,
String[] mimeTypes, String[] values,
int x, int y,
int screenX, int screenY,
int dndActionId)
{
lockPage();
try {
log.finest("dispatchDragOperation: " + x + "," + y
+ " dndCommand:" + commandId
+ " dndAction" + dndActionId);
if (isDisposed) {
log.fine("DnD event for a disposed web page.");
return 0;
}
return twkProcessDrag(getPage(),
commandId,
mimeTypes, values,
x, y,
screenX, screenY,
dndActionId);
} finally {
unlockPage();
}
}
public void confirmStartDrag() {
if (uiClient != null)
uiClient.confirmStartDrag();
}
public boolean isDragConfirmed(){
return (uiClient != null)
? uiClient.isDragConfirmed()
: false;
}
public int[] getClientTextLocation(int index) {
lockPage();
try {
if (isDisposed) {
log.fine("getClientTextLocation() request for a disposed web page.");
return new int[] { 0, 0, 0, 0 };
}
Invoker.getInvoker().checkEventThread();
return twkGetTextLocation(getPage(), index);
} finally {
unlockPage();
}
}
public int getClientLocationOffset(int x, int y) {
lockPage();
try {
if (isDisposed) {
log.fine("getClientLocationOffset() request for a disposed web page.");
return 0;
}
Invoker.getInvoker().checkEventThread();
return twkGetInsertPositionOffset(getPage());
} finally {
unlockPage();
}
}
public int getClientInsertPositionOffset() {
lockPage();
try {
if (isDisposed) {
log.fine("getClientInsertPositionOffset() request for a disposed web page.");
return 0;
}
return twkGetInsertPositionOffset(getPage());
} finally {
unlockPage();
}
}
public int getClientCommittedTextLength() {
lockPage();
try {
if (isDisposed) {
log.fine("getClientCommittedTextOffset() request for a disposed web page.");
return 0;
}
return twkGetCommittedTextLength(getPage());
} finally {
unlockPage();
}
}
public String getClientCommittedText() {
lockPage();
try {
if (isDisposed) {
log.fine("getClientCommittedText() request for a disposed web page.");
return "";
}
return twkGetCommittedText(getPage());
} finally {
unlockPage();
}
}
public String getClientSelectedText() {
lockPage();
try {
if (isDisposed) {
log.fine("getClientSelectedText() request for a disposed web page.");
return "";
}
final String selectedText = twkGetSelectedText(getPage());
return selectedText != null ? selectedText : "";
} finally {
unlockPage();
}
}
public void dispose() {
lockPage();
try {
log.finer("dispose");
stop();
dropRenderFrames();
isDisposed = true;
twkDestroyPage(pPage);
pPage = 0;
for (long frameID : frames) {
log.fine("Undestroyed frame view: " + frameID);
}
frames.clear();
if (backbuffer != null) {
backbuffer.deref();
backbuffer = null;
}
} finally {
unlockPage();
}
}
public String getName(long frameID) {
lockPage();
try {
log.fine("Get Name: frame = " + frameID);
if (isDisposed) {
log.fine("getName() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
return twkGetName(frameID);
} finally {
unlockPage();
}
}
public String getURL(long frameID) {
lockPage();
try {
log.fine("Get URL: frame = " + frameID);
if (isDisposed) {
log.fine("getURL() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
return twkGetURL(frameID);
} finally {
unlockPage();
}
}
public String getEncoding() {
lockPage();
try {
log.fine("Get encoding");
if (isDisposed) {
log.fine("getEncoding() request for a disposed web page.");
return null;
}
return twkGetEncoding(getPage());
} finally {
unlockPage();
}
}
public void setEncoding(String encoding) {
lockPage();
try {
log.fine("Set encoding: encoding = " + encoding);
if (isDisposed) {
log.fine("setEncoding() request for a disposed web page.");
return;
}
if (encoding != null && !encoding.isEmpty()) {
twkSetEncoding(getPage(), encoding);
}
} finally {
unlockPage();
}
}
public String getInnerText(long frameID) {
lockPage();
try {
log.fine("Get inner text: frame = " + frameID);
if (isDisposed) {
log.fine("getInnerText() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
return twkGetInnerText(frameID);
} finally {
unlockPage();
}
}
public String getRenderTree(long frameID) {
lockPage();
try {
log.fine("Get render tree: frame = " + frameID);
if (isDisposed) {
log.fine("getRenderTree() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
return twkGetRenderTree(frameID);
} finally {
unlockPage();
}
}
public int getUnloadEventListenersCount(long frameID) {
lockPage();
try {
log.fine("frame: " + frameID);
if (isDisposed) {
log.fine("request for a disposed web page.");
return 0;
}
if (!frames.contains(frameID)) {
return 0;
}
return twkGetUnloadEventListenersCount(frameID);
} finally {
unlockPage();
}
}
public String getContentType(long frameID) {
lockPage();
try {
log.fine("Get content type: frame = " + frameID);
if (isDisposed) {
log.fine("getContentType() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
return twkGetContentType(frameID);
} finally {
unlockPage();
}
}
public String getTitle(long frameID) {
lockPage();
try {
log.fine("Get title: frame = " + frameID);
if (isDisposed) {
log.fine("getTitle() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
return twkGetTitle(frameID);
} finally {
unlockPage();
}
}
public WCImage getIcon(long frameID) {
lockPage();
try {
log.fine("Get icon: frame = " + frameID);
if (isDisposed) {
log.fine("getIcon() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
String iconURL = twkGetIconURL(frameID);
if (iconURL != null && !iconURL.isEmpty()) {
return WCGraphicsManager.getGraphicsManager().getIconImage(iconURL);
}
return null;
} finally {
unlockPage();
}
}
public void open(final long frameID, final String url) {
lockPage();
try {
log.fine("Open URL: " + url);
if (isDisposed) {
log.fine("open() request for a disposed web page.");
return;
}
if (!frames.contains(frameID)) {
return;
}
if (twkIsLoading(frameID)) {
Invoker.getInvoker().postOnEventThread(() -> {
twkOpen(frameID, url);
});
} else {
twkOpen(frameID, url);
}
} finally {
unlockPage();
}
}
public void load(final long frameID, final String text, final String contentType) {
lockPage();
try {
log.fine("Load text: " + text);
if (text == null) {
return;
}
if (isDisposed) {
log.fine("load() request for a disposed web page.");
return;
}
if (!frames.contains(frameID)) {
return;
}
if (twkIsLoading(frameID)) {
Invoker.getInvoker().postOnEventThread(() -> {
twkLoad(frameID, text, contentType);
});
} else {
twkLoad(frameID, text, contentType);
}
} finally {
unlockPage();
}
}
public void stop(final long frameID) {
lockPage();
try {
log.fine("Stop loading: frame = " + frameID);
String url;
String contentType;
if (isDisposed) {
log.fine("cancel() request for a disposed web page.");
return;
}
if (!frames.contains(frameID)) {
return;
}
url = twkGetURL(frameID);
contentType = twkGetContentType(frameID);
twkStop(frameID);
fireLoadEvent(frameID, LoadListenerClient.LOAD_STOPPED, url, contentType, 1.0, 0);
} finally {
unlockPage();
}
}
public void stop() {
lockPage();
try {
log.fine("Stop loading sync");
if (isDisposed) {
log.fine("stopAll() request for a disposed web page.");
return;
}
twkStopAll(getPage());
} finally {
unlockPage();
}
}
public void refresh(final long frameID) {
lockPage();
try {
log.fine("Refresh: frame = " + frameID);
if (isDisposed) {
log.fine("refresh() request for a disposed web page.");
return;
}
if (!frames.contains(frameID)) {
return;
}
twkRefresh(frameID);
} finally {
unlockPage();
}
}
public BackForwardList createBackForwardList() {
return new BackForwardList(this);
}
public boolean goBack() {
lockPage();
try {
log.fine("Go back");
if (isDisposed) {
log.fine("goBack() request for a disposed web page.");
return false;
}
return twkGoBackForward(getPage(), -1);
} finally {
unlockPage();
}
}
public boolean goForward() {
lockPage();
try {
log.fine("Go forward");
if (isDisposed) {
log.fine("goForward() request for a disposed web page.");
return false;
}
return twkGoBackForward(getPage(), 1);
} finally {
unlockPage();
}
}
public boolean copy() {
lockPage();
try {
log.fine("Copy");
if (isDisposed) {
log.fine("copy() request for a disposed web page.");
return false;
}
long frameID = getMainFrame();
if (!frames.contains(frameID)) {
return false;
}
return twkCopy(frameID);
} finally {
unlockPage();
}
}
public boolean find(String stringToFind, boolean forward, boolean wrap, boolean matchCase) {
lockPage();
try {
log.fine("Find in page: stringToFind = " + stringToFind + ", " +
(forward ? "forward" : "backward") + (wrap ? ", wrap" : "") + (matchCase ? ", matchCase" : ""));
if (isDisposed) {
log.fine("find() request for a disposed web page.");
return false;
}
return twkFindInPage(getPage(), stringToFind, forward, wrap, matchCase);
} finally {
unlockPage();
}
}
public boolean find(long frameID,
String stringToFind, boolean forward, boolean wrap, boolean matchCase)
{
lockPage();
try {
log.fine("Find in frame: stringToFind = " + stringToFind + ", " +
(forward ? "forward" : "backward") + (wrap ? ", wrap" : "") + (matchCase ? ", matchCase" : ""));
if (isDisposed) {
log.fine("find() request for a disposed web page.");
return false;
}
if (!frames.contains(frameID)) {
return false;
}
return twkFindInFrame(frameID, stringToFind, forward, wrap, matchCase);
} finally {
unlockPage();
}
}
public void overridePreference(String key, String value) {
lockPage();
try {
twkOverridePreference(getPage(), key, value);
} finally {
unlockPage();
}
}
public void resetToConsistentStateBeforeTesting() {
lockPage();
try {
twkResetToConsistentStateBeforeTesting(getPage());
} finally {
unlockPage();
}
}
public float getZoomFactor(boolean textOnly) {
lockPage();
try {
log.fine("Get zoom factor, textOnly=" + textOnly);
if (isDisposed) {
log.fine("getZoomFactor() request for a disposed web page.");
return 1.0f;
}
long frameID = getMainFrame();
if (!frames.contains(frameID)) {
return 1.0f;
}
return twkGetZoomFactor(frameID, textOnly);
} finally {
unlockPage();
}
}
public void setZoomFactor(float zoomFactor, boolean textOnly) {
lockPage();
try {
log.fine(String.format("Set zoom factor %.2f, textOnly=%b", zoomFactor, textOnly));
if (isDisposed) {
log.fine("setZoomFactor() request for a disposed web page.");
return;
}
long frameID = getMainFrame();
if ((frameID == 0) || !frames.contains(frameID)) {
return;
}
twkSetZoomFactor(frameID, zoomFactor, textOnly);
} finally {
unlockPage();
}
}
public void setFontSmoothingType(int fontSmoothingType) {
this.fontSmoothingType = fontSmoothingType;
repaintAll();
}
public void reset(long frameID) {
lockPage();
try {
log.fine("Reset: frame = " + frameID);
if (isDisposed) {
log.fine("reset() request for a disposed web page.");
return;
}
if ((frameID == 0) || !frames.contains(frameID)) {
return;
}
twkReset(frameID);
} finally {
unlockPage();
}
}
public Object executeScript(long frameID, String script) throws JSException {
lockPage();
try {
log.fine("execute script: \"" + script + "\" in frame = " + frameID);
if (isDisposed) {
log.fine("executeScript() request for a disposed web page.");
return null;
}
if ((frameID == 0) || !frames.contains(frameID)) {
return null;
}
return twkExecuteScript(frameID, script);
} finally {
unlockPage();
}
}
public long getMainFrame() {
lockPage();
try {
log.finer("getMainFrame: page = " + pPage);
if (isDisposed) {
log.fine("getMainFrame() request for a disposed web page.");
return 0L;
}
long mainFrameID = twkGetMainFrame(getPage());
log.finer("Main frame = " + mainFrameID);
frames.add(mainFrameID);
return mainFrameID;
} finally {
unlockPage();
}
}
public long getParentFrame(long childID) {
lockPage();
try {
log.fine("getParentFrame: child = " + childID);
if (isDisposed) {
log.fine("getParentFrame() request for a disposed web page.");
return 0L;
}
if (!frames.contains(childID)) {
return 0L;
}
return twkGetParentFrame(childID);
} finally {
unlockPage();
}
}
public List<Long> getChildFrames(long parentID) {
lockPage();
try {
log.fine("getChildFrames: parent = " + parentID);
if (isDisposed) {
log.fine("getChildFrames() request for a disposed web page.");
return null;
}
if (!frames.contains(parentID)) {
return null;
}
long[] children = twkGetChildFrames(parentID);
List<Long> childrenList = new LinkedList<Long>();
for (long child : children) {
childrenList.add(Long.valueOf(child));
}
return childrenList;
} finally {
unlockPage();
}
}
public WCRectangle getVisibleRect(long frameID) {
lockPage();
try {
if (!frames.contains(frameID)) {
return null;
}
int[] arr = twkGetVisibleRect(frameID);
if (arr != null) {
return new WCRectangle(arr[0], arr[1], arr[2], arr[3]);
}
return null;
} finally {
unlockPage();
}
}
public void scrollToPosition(long frameID, WCPoint p) {
lockPage();
try {
if (!frames.contains(frameID)) {
return;
}
twkScrollToPosition(frameID, p.getIntX(), p.getIntY());
} finally {
unlockPage();
}
}
public WCSize getContentSize(long frameID) {
lockPage();
try {
if (!frames.contains(frameID)) {
return null;
}
int[] arr = twkGetContentSize(frameID);
if (arr != null) {
return new WCSize(arr[0], arr[1]);
}
return null;
} finally {
unlockPage();
}
}
public Document getDocument(long frameID) {
lockPage();
try {
log.fine("getDocument");
if (isDisposed) {
log.fine("getDocument() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
return twkGetDocument(frameID);
} finally {
unlockPage();
}
}
public Element getOwnerElement(long frameID) {
lockPage();
try {
log.fine("getOwnerElement");
if (isDisposed) {
log.fine("getOwnerElement() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
return twkGetOwnerElement(frameID);
} finally {
unlockPage();
}
}
public boolean executeCommand(String command, String value) {
lockPage();
try {
if (log.isLoggable(Level.FINE)) {
log.fine("command: [{0}], value: [{1}]",
new Object[] {command, value});
}
if (isDisposed) {
log.fine("Web page is already disposed");
return false;
}
boolean result = twkExecuteCommand(getPage(), command, value);
log.fine("result: [{0}]", result);
return result;
} finally {
unlockPage();
}
}
public boolean queryCommandEnabled(String command) {
lockPage();
try {
log.fine("command: [{0}]", command);
if (isDisposed) {
log.fine("Web page is already disposed");
return false;
}
boolean result = twkQueryCommandEnabled(getPage(), command);
log.fine("result: [{0}]", result);
return result;
} finally {
unlockPage();
}
}
public boolean queryCommandState(String command) {
lockPage();
try {
log.fine("command: [{0}]", command);
if (isDisposed) {
log.fine("Web page is already disposed");
return false;
}
boolean result = twkQueryCommandState(getPage(), command);
log.fine("result: [{0}]", result);
return result;
} finally {
unlockPage();
}
}
public String queryCommandValue(String command) {
lockPage();
try {
log.fine("command: [{0}]", command);
if (isDisposed) {
log.fine("Web page is already disposed");
return null;
}
String result = twkQueryCommandValue(getPage(), command);
log.fine("result: [{0}]", result);
return result;
} finally {
unlockPage();
}
}
public boolean isEditable() {
lockPage();
try {
log.fine("isEditable");
if (isDisposed) {
log.fine("isEditable() request for a disposed web page.");
return false;
}
return twkIsEditable(getPage());
} finally {
unlockPage();
}
}
public void setEditable(boolean editable) {
lockPage();
try {
log.fine("setEditable");
if (isDisposed) {
log.fine("setEditable() request for a disposed web page.");
return;
}
twkSetEditable(getPage(), editable);
} finally {
unlockPage();
}
}
public String getHtml(long frameID) {
lockPage();
try {
log.fine("getHtml");
if (isDisposed) {
log.fine("getHtml() request for a disposed web page.");
return null;
}
if (!frames.contains(frameID)) {
return null;
}
return twkGetHtml(frameID);
} finally {
unlockPage();
}
}
public int beginPrinting(float width, float height) {
lockPage();
try {
if (isDisposed) {
log.warning("beginPrinting() called for a disposed web page.");
return 0;
}
AtomicReference<Integer> retVal = new AtomicReference<>(0);
final CountDownLatch l = new CountDownLatch(1);
Invoker.getInvoker().invokeOnEventThread(() -> {
try {
int nPages = twkBeginPrinting(getPage(), width, height);
retVal.set(nPages);
} finally {
l.countDown();
}
});
try {
l.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return retVal.get();
} finally {
unlockPage();
}
}
public void endPrinting() {
lockPage();
try {
if (isDisposed) {
log.warning("endPrinting() called for a disposed web page.");
return;
}
final CountDownLatch l = new CountDownLatch(1);
Invoker.getInvoker().invokeOnEventThread(() -> {
try {
twkEndPrinting(getPage());
} finally {
l.countDown();
}
});
try {
l.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} finally {
unlockPage();
}
}
public void print(final WCGraphicsContext gc, final int pageNumber, final float width) {
lockPage();
try {
if (isDisposed) {
log.warning("print() called for a disposed web page.");
return;
}
final WCRenderQueue rq = WCGraphicsManager.getGraphicsManager().
createRenderQueue(null, true);
final CountDownLatch l = new CountDownLatch(1);
Invoker.getInvoker().invokeOnEventThread(() -> {
try {
twkPrint(getPage(), rq, pageNumber, width);
} finally {
l.countDown();
}
});
try {
l.await();
} catch (InterruptedException e) {
rq.dispose();
return;
}
rq.decode(gc);
} finally {
unlockPage();
}
}
public int getPageHeight() {
return getFrameHeight(getMainFrame());
}
public int getFrameHeight(long frameID) {
lockPage();
try {
log.fine("Get page height");
if (isDisposed) {
log.fine("getFrameHeight() request for a disposed web page.");
return 0;
}
if (!frames.contains(frameID)) {
return 0;
}
int height = twkGetFrameHeight(frameID);
log.fine("Height = " + height);
return height;
} finally {
unlockPage();
}
}
public float adjustFrameHeight(long frameID,
float oldTop, float oldBottom, float bottomLimit)
{
lockPage();
try {
log.fine("Adjust page height");
if (isDisposed) {
log.fine("adjustFrameHeight() request for a disposed web page.");
return 0;
}
if (!frames.contains(frameID)) {
return 0;
}
return twkAdjustFrameHeight(frameID, oldTop, oldBottom, bottomLimit);
} finally {
unlockPage();
}
}
public boolean getUsePageCache() {
lockPage();
try {
return twkGetUsePageCache(getPage());
} finally {
unlockPage();
}
}
public void setUsePageCache(boolean usePageCache) {
lockPage();
try {
twkSetUsePageCache(getPage(), usePageCache);
} finally {
unlockPage();
}
}
public boolean () {
lockPage();
try {
boolean result = twkGetDeveloperExtrasEnabled(getPage());
log.fine("Getting developerExtrasEnabled, result: [{0}]", result);
return result;
} finally {
unlockPage();
}
}
public void (boolean enabled) {
lockPage();
try {
log.fine("Setting developerExtrasEnabled, value: [{0}]", enabled);
twkSetDeveloperExtrasEnabled(getPage(), enabled);
} finally {
unlockPage();
}
}
public boolean isJavaScriptEnabled() {
lockPage();
try {
return twkIsJavaScriptEnabled(getPage());
} finally {
unlockPage();
}
}
public void setJavaScriptEnabled(boolean enable) {
lockPage();
try {
twkSetJavaScriptEnabled(getPage(), enable);
} finally {
unlockPage();
}
}
public boolean () {
lockPage();
try {
return twkIsContextMenuEnabled(getPage());
} finally {
unlockPage();
}
}
public void (boolean enable) {
lockPage();
try {
twkSetContextMenuEnabled(getPage(), enable);
} finally {
unlockPage();
}
}
public void setUserStyleSheetLocation(String url) {
lockPage();
try {
twkSetUserStyleSheetLocation(getPage(), url);
} finally {
unlockPage();
}
}
public String getUserAgent() {
lockPage();
try {
return twkGetUserAgent(getPage());
} finally {
unlockPage();
}
}
public void setUserAgent(String userAgent) {
lockPage();
try {
twkSetUserAgent(getPage(), userAgent);
} finally {
unlockPage();
}
}
public void setLocalStorageDatabasePath(String path) {
lockPage();
try {
twkSetLocalStorageDatabasePath(getPage(), path);
} finally {
unlockPage();
}
}
public void setLocalStorageEnabled(boolean enabled) {
lockPage();
try {
twkSetLocalStorageEnabled(getPage(), enabled);
} finally {
unlockPage();
}
}
public void connectInspectorFrontend() {
lockPage();
try {
log.fine("Connecting inspector frontend");
twkConnectInspectorFrontend(getPage());
} finally {
unlockPage();
}
}
public void disconnectInspectorFrontend() {
lockPage();
try {
log.fine("Disconnecting inspector frontend");
twkDisconnectInspectorFrontend(getPage());
} finally {
unlockPage();
}
}
public void dispatchInspectorMessageFromFrontend(String message) {
lockPage();
try {
if (log.isLoggable(Level.FINE)) {
log.fine("Dispatching inspector message from frontend, "
+ "message: [{0}]", message);
}
twkDispatchInspectorMessageFromFrontend(getPage(), message);
} finally {
unlockPage();
}
}
private void fwkFrameCreated(long frameID) {
log.fine("Frame created: frame = " + frameID);
if (frames.contains(frameID)) {
log.fine("Error in fwkFrameCreated: frame is already in frames");
return;
}
frames.add(frameID);
}
private void fwkFrameDestroyed(long frameID) {
log.fine("Frame destroyed: frame = " + frameID);
if (!frames.contains(frameID)) {
log.fine("Error in fwkFrameDestroyed: frame is not found in frames");
return;
}
frames.remove(frameID);
}
private void fwkRepaint(int x, int y, int w, int h) {
lockPage();
try {
if (paintLog.isLoggable(Level.FINEST)) {
paintLog.finest("x: {0}, y: {1}, w: {2}, h: {3}",
new Object[] {x, y, w, h});
}
addDirtyRect(new WCRectangle(x, y, w, h));
} finally {
unlockPage();
}
}
private void fwkScroll(int x, int y, int w, int h, int deltaX, int deltaY) {
if (paintLog.isLoggable(Level.FINEST)) {
paintLog.finest("Scroll: " + x + " " + y + " " + w + " " + h + " " + deltaX + " " + deltaY);
}
if (pageClient == null || !pageClient.isBackBufferSupported()) {
paintLog.finest("blit scrolling is switched off");
return;
}
scroll(x, y, w, h, deltaX, deltaY);
}
private void fwkTransferFocus(boolean forward) {
log.finer("Transfer focus " + (forward ? "forward" : "backward"));
if (pageClient != null) {
pageClient.transferFocus(forward);
}
}
private void fwkSetCursor(long id) {
log.finer("Set cursor: " + id);
if (pageClient != null) {
pageClient.setCursor(id);
}
}
private void fwkSetFocus(boolean focus) {
log.finer("Set focus: " + (focus ? "true" : "false"));
if (pageClient != null) {
pageClient.setFocus(focus);
}
}
private void fwkSetTooltip(String tooltip) {
log.finer("Set tooltip: " + tooltip);
if (pageClient != null) {
pageClient.setTooltip(tooltip);
}
}
private void fwkPrint() {
log.finer("Print");
if (uiClient != null) {
uiClient.print();
}
}
private void fwkSetRequestURL(long pFrame, int id, String url) {
log.finer("Set request URL: id = " + id + ", url = " + url);
synchronized (requestURLs) {
requestURLs.put(id, url);
}
}
private void fwkRemoveRequestURL(long pFrame, int id) {
log.finer("Set request URL: id = " + id);
synchronized (requestURLs) {
requestURLs.remove(id);
requestStarted.remove(id);
}
}
private WebPage fwkCreateWindow(
boolean menu, boolean status, boolean toolbar, boolean resizable) {
log.finer("Create window");
if (uiClient != null) {
return uiClient.createPage(menu, status, toolbar, resizable);
}
return null;
}
private void fwkShowWindow() {
log.finer("Show window");
if (uiClient != null) {
uiClient.showView();
}
}
private void fwkCloseWindow() {
log.finer("Close window");
if (permitCloseWindowAction()) {
if (uiClient != null) {
uiClient.closePage();
}
}
}
private WCRectangle fwkGetWindowBounds() {
log.fine("Get window bounds");
if (uiClient != null) {
WCRectangle bounds = uiClient.getViewBounds();
if (bounds != null) {
return bounds;
}
}
return fwkGetPageBounds();
}
private void fwkSetWindowBounds(int x, int y, int w, int h) {
log.finer("Set window bounds: " + x + " " + y + " " + w + " " + h);
if (uiClient != null) {
uiClient.setViewBounds(new WCRectangle(x, y, w, h));
}
}
private WCRectangle fwkGetPageBounds() {
log.finer("Get page bounds");
return new WCRectangle(0, 0, width, height);
}
private void fwkSetScrollbarsVisible(boolean visible) {
}
private void fwkSetStatusbarText(String text) {
log.finer("Set statusbar text: " + text);
if (uiClient != null) {
uiClient.setStatusbarText(text);
}
}
private String[] fwkChooseFile(String initialFileName, boolean multiple, String mimeFilters) {
log.finer("Choose file, initial=" + initialFileName);
return uiClient != null
? uiClient.chooseFile(initialFileName, multiple, mimeFilters)
: null;
}
private void fwkStartDrag(
Object image,
int imageOffsetX, int imageOffsetY,
int eventPosX, int eventPosY,
String[] mimeTypes, Object[] values,
boolean isImageSource)
{
log.finer("Start drag: ");
if (uiClient != null) {
uiClient.startDrag(
WCImage.getImage(image),
imageOffsetX, imageOffsetY,
eventPosX, eventPosY,
mimeTypes, values,
isImageSource);
}
}
private WCPoint fwkScreenToWindow(WCPoint ptScreen) {
log.finer("fwkScreenToWindow");
if (pageClient != null) {
return pageClient.screenToWindow(ptScreen);
}
return ptScreen;
}
private WCPoint fwkWindowToScreen(WCPoint ptWindow) {
log.finer("fwkWindowToScreen");
if (pageClient != null) {
return pageClient.windowToScreen(ptWindow);
}
return ptWindow;
}
private void fwkAlert(String text) {
log.fine("JavaScript alert(): text = " + text);
if (uiClient != null) {
uiClient.alert(text);
}
}
private boolean fwkConfirm(String text) {
log.fine("JavaScript confirm(): text = " + text);
if (uiClient != null) {
return uiClient.confirm(text);
}
return false;
}
private String fwkPrompt(String text, String defaultValue) {
log.fine("JavaScript prompt(): text = " + text + ", default = " + defaultValue);
if (uiClient != null) {
return uiClient.prompt(text, defaultValue);
}
return null;
}
private boolean fwkCanRunBeforeUnloadConfirmPanel() {
log.fine("JavaScript canRunBeforeUnloadConfirmPanel()");
if (uiClient != null) {
return uiClient.canRunBeforeUnloadConfirmPanel();
}
return false;
}
private boolean fwkRunBeforeUnloadConfirmPanel(String message) {
log.fine("JavaScript runBeforeUnloadConfirmPanel(): message = " + message);
if (uiClient != null) {
return uiClient.runBeforeUnloadConfirmPanel(message);
}
return false;
}
private void fwkAddMessageToConsole(String message, int lineNumber,
String sourceId)
{
log.fine("fwkAddMessageToConsole(): message = " + message
+ ", lineNumber = " + lineNumber + ", sourceId = " + sourceId);
if (pageClient != null) {
pageClient.addMessageToConsole(message, lineNumber, sourceId);
}
}
private void fwkFireLoadEvent(long frameID, int state,
String url, String contentType,
double progress, int errorCode)
{
log.finer("Load event: pFrame = " + frameID + ", state = " + state +
", url = " + url + ", contenttype=" + contentType +
", progress = " + progress + ", error = " + errorCode);
fireLoadEvent(frameID, state, url, contentType, progress, errorCode);
}
private void fwkFireResourceLoadEvent(long frameID, int state,
int id, String contentType,
double progress, int errorCode)
{
log.finer("Resource load event: pFrame = " + frameID + ", state = " + state +
", id = " + id + ", contenttype=" + contentType +
", progress = " + progress + ", error = " + errorCode);
String url = requestURLs.get(id);
if (url == null) {
log.fine("Error in fwkFireResourceLoadEvent: unknown request id " + id);
return;
}
int eventState = state;
if (state == LoadListenerClient.RESOURCE_STARTED) {
if (requestStarted.contains(id)) {
eventState = LoadListenerClient.RESOURCE_REDIRECTED;
} else {
requestStarted.add(id);
}
}
fireResourceLoadEvent(frameID, eventState, url, contentType, progress, errorCode);
}
private boolean fwkPermitNavigateAction(long pFrame, String url) {
log.fine("Policy: permit NAVIGATE: pFrame = " + pFrame + ", url = " + url);
if (policyClient != null) {
return policyClient.permitNavigateAction(pFrame, str2url(url));
}
return true;
}
private boolean fwkPermitRedirectAction(long pFrame, String url) {
log.fine("Policy: permit REDIRECT: pFrame = " + pFrame + ", url = " + url);
if (policyClient != null) {
return policyClient.permitRedirectAction(pFrame, str2url(url));
}
return true;
}
private boolean fwkPermitAcceptResourceAction(long pFrame, String url) {
log.fine("Policy: permit ACCEPT_RESOURCE: pFrame + " + pFrame + ", url = " + url);
if (policyClient != null) {
return policyClient.permitAcceptResourceAction(pFrame, str2url(url));
}
return true;
}
private boolean fwkPermitSubmitDataAction(long pFrame, String url,
String httpMethod, boolean isSubmit)
{
log.fine("Policy: permit " + (isSubmit ? "" : "RE") + "SUBMIT_DATA: pFrame = " +
pFrame + ", url = " + url + ", httpMethod = " + httpMethod);
if (policyClient != null) {
if (isSubmit) {
return policyClient.permitSubmitDataAction(pFrame, str2url(url), httpMethod);
} else {
return policyClient.permitResubmitDataAction(pFrame, str2url(url), httpMethod);
}
}
return true;
}
private boolean fwkPermitEnableScriptsAction(long pFrame, String url) {
log.fine("Policy: permit ENABLE_SCRIPTS: pFrame + " + pFrame + ", url = " + url);
if (policyClient != null) {
return policyClient.permitEnableScriptsAction(pFrame, str2url(url));
}
return true;
}
private boolean fwkPermitNewWindowAction(long pFrame, String url) {
log.fine("Policy: permit NEW_PAGE: pFrame = " + pFrame + ", url = " + url);
if (policyClient != null) {
return policyClient.permitNewPageAction(pFrame, str2url(url));
}
return true;
}
private boolean permitCloseWindowAction() {
log.fine("Policy: permit CLOSE_PAGE");
if (policyClient != null) {
return policyClient.permitClosePageAction(getMainFrame());
}
return true;
}
private void fwkRepaintAll() {
log.fine("Repainting the entire page");
repaintAll();
}
private boolean fwkSendInspectorMessageToFrontend(String message) {
if (log.isLoggable(Level.FINE)) {
log.fine("Sending inspector message to frontend, message: [{0}]",
message);
}
boolean result = false;
if (inspectorClient != null) {
log.fine("Invoking inspector client");
result = inspectorClient.sendMessageToFrontend(message);
}
if (log.isLoggable(Level.FINE)) {
log.fine("Result: [{0}]", result);
}
return result;
}
public static int getWorkerThreadCount() {
return twkWorkerThreadCount();
}
private static native int twkWorkerThreadCount();
private void fwkDidClearWindowObject(long pContext, long pWindowObject) {
if (pageClient != null) {
pageClient.didClearWindowObject(pContext, pWindowObject);
}
}
private URL str2url(String url) {
try {
return newURL(url);
} catch (MalformedURLException ex) {
log.fine("Exception while converting \"" + url + "\" to URL", ex);
}
return null;
}
private void fireLoadEvent(long frameID, int state, String url,
String contentType, double progress, int errorCode)
{
for (LoadListenerClient l : loadListenerClients) {
l.dispatchLoadEvent(frameID, state, url, contentType, progress, errorCode);
}
}
private void fireResourceLoadEvent(long frameID, int state, String url,
String contentType, double progress, int errorCode)
{
for (LoadListenerClient l : loadListenerClients) {
l.dispatchResourceLoadEvent(frameID, state, url, contentType, progress, errorCode);
}
}
private void repaintAll() {
dirtyRects.clear();
addDirtyRect(new WCRectangle(0, 0, width, height));
}
int test_getFramesCount() {
return frames.size();
}
private static native void twkInitWebCore(boolean useJIT, boolean useDFGJIT, boolean useCSS3D);
private native long twkCreatePage(boolean editable);
private native void twkInit(long pPage, boolean usePlugins, float devicePixelScale);
private native void twkDestroyPage(long pPage);
private native long twkGetMainFrame(long pPage);
private native long twkGetParentFrame(long pFrame);
private native long[] twkGetChildFrames(long pFrame);
private native String twkGetName(long pFrame);
private native String twkGetURL(long pFrame);
private native String twkGetInnerText(long pFrame);
private native String twkGetRenderTree(long pFrame);
private native String twkGetContentType(long pFrame);
private native String twkGetTitle(long pFrame);
private native String twkGetIconURL(long pFrame);
private native static Document twkGetDocument(long pFrame);
private native static Element twkGetOwnerElement(long pFrame);
private native void twkOpen(long pFrame, String url);
private native void twkOverridePreference(long pPage, String key, String value);
private native void twkResetToConsistentStateBeforeTesting(long pPage);
private native void twkLoad(long pFrame, String text, String contentType);
private native boolean twkIsLoading(long pFrame);
private native void twkStop(long pFrame);
private native void twkStopAll(long pPage);
private native void twkRefresh(long pFrame);
private native boolean twkGoBackForward(long pPage, int distance);
private native boolean twkCopy(long pFrame);
private native boolean twkFindInPage(long pPage,
String stringToFind, boolean forward,
boolean wrap, boolean matchCase);
private native boolean twkFindInFrame(long pFrame,
String stringToFind, boolean forward,
boolean wrap, boolean matchCase);
private native float twkGetZoomFactor(long pFrame, boolean textOnly);
private native void twkSetZoomFactor(long pFrame, float zoomFactor, boolean textOnly);
private native Object twkExecuteScript(long pFrame, String script);
private native void twkReset(long pFrame);
private native int twkGetFrameHeight(long pFrame);
private native int twkBeginPrinting(long pPage, float width, float height);
private native void twkEndPrinting(long pPage);
private native void twkPrint(long pPage, WCRenderQueue gc, int pageNumber, float width);
private native float twkAdjustFrameHeight(long pFrame, float oldTop, float oldBottom, float bottomLimit);
private native int[] twkGetVisibleRect(long pFrame);
private native void twkScrollToPosition(long pFrame, int x, int y);
private native int[] twkGetContentSize(long pFrame);
private native void twkSetTransparent(long pFrame, boolean isTransparent);
private native void twkSetBackgroundColor(long pFrame, int backgroundColor);
private native void twkSetBounds(long pPage, int x, int y, int w, int h);
private native void twkPrePaint(long pPage);
private native void twkUpdateContent(long pPage, WCRenderQueue rq, int x, int y, int w, int h);
private native void twkPostPaint(long pPage, WCRenderQueue rq,
int x, int y, int w, int h);
private native String twkGetEncoding(long pPage);
private native void twkSetEncoding(long pPage, String encoding);
private native void twkProcessFocusEvent(long pPage, int id, int direction);
private native boolean twkProcessKeyEvent(long pPage, int type, String text,
String keyIdentifier,
int windowsVirtualKeyCode,
boolean shift, boolean ctrl,
boolean alt, boolean meta, double when);
private native boolean twkProcessMouseEvent(long pPage, int id,
int button, int clickCount,
int x, int y, int sx, int sy,
boolean shift, boolean control, boolean alt, boolean meta,
boolean popupTrigger, double when);
private native boolean twkProcessMouseWheelEvent(long pPage,
int x, int y, int sx, int sy,
float dx, float dy,
boolean shift, boolean control, boolean alt, boolean meta,
double when);
private native boolean twkProcessInputTextChange(long pPage, String committed, String composed,
int[] attributes, int caretPosition);
private native boolean twkProcessCaretPositionChange(long pPage, int caretPosition);
private native int[] twkGetTextLocation(long pPage, int charIndex);
private native int twkGetInsertPositionOffset(long pPage);
private native int twkGetCommittedTextLength(long pPage);
private native String twkGetCommittedText(long pPage);
private native String twkGetSelectedText(long pPage);
private native int twkProcessDrag(long page,
int commandId,
String[] mimeTypes, String[] values,
int x, int y,
int screenX, int screenY,
int dndActionId);
private native boolean twkExecuteCommand(long page, String command,
String value);
private native boolean twkQueryCommandEnabled(long page, String command);
private native boolean twkQueryCommandState(long page, String command);
private native String twkQueryCommandValue(long page, String command);
private native boolean twkIsEditable(long page);
private native void twkSetEditable(long page, boolean editable);
private native String twkGetHtml(long pFrame);
private native boolean twkGetUsePageCache(long page);
private native void twkSetUsePageCache(long page, boolean usePageCache);
private native boolean (long page);
private native void (long page,
boolean enabled);
private native boolean twkIsJavaScriptEnabled(long page);
private native void twkSetJavaScriptEnabled(long page, boolean enable);
private native boolean (long page);
private native void (long page, boolean enable);
private native void twkSetUserStyleSheetLocation(long page, String url);
private native String twkGetUserAgent(long page);
private native void twkSetUserAgent(long page, String userAgent);
private native void twkSetLocalStorageDatabasePath(long page, String path);
private native void twkSetLocalStorageEnabled(long page, boolean enabled);
private native int twkGetUnloadEventListenersCount(long pFrame);
private native void twkConnectInspectorFrontend(long pPage);
private native void twkDisconnectInspectorFrontend(long pPage);
private native void twkDispatchInspectorMessageFromFrontend(long pPage,
String message);
private static native void twkDoJSCGarbageCollection();
}