com.sun.webkit.BackForwardList Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.webkit;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import com.sun.webkit.event.WCChangeEvent;
import com.sun.webkit.event.WCChangeListener;
import com.sun.webkit.graphics.WCImage;
import static com.sun.webkit.network.URLs.newURL;
public final class BackForwardList {
public static final class Entry {
/**
* Native pointer to the HistoryItem object.
* If 0, the corresponding object has already been destroyed.
*/
private long pitem = 0;
// Native pointer to the Page object.
private long ppage = 0;
private Entry[] children;
private URL url;
private String title;
private Date lastVisitedDate;
private WCImage icon;
private String target;
private boolean isTargetItem;
// Only called from the native code.
private Entry(long pitem, long ppage) {
this.pitem = pitem;
this.ppage = ppage;
// When the Entry is disposed its fields may be
// left uninitialized. As the Entry may still
// be referenced from a global history, the fields
// should get their initial values here.
getURL();
getTitle();
getLastVisitedDate();
getIcon();
getTarget();
isTargetItem();
getChildren();
}
// Only called from the native code.
private void notifyItemDestroyed() {
pitem = 0;
}
// Called from the native code as well.
private void notifyItemChanged() {
for (WCChangeListener l : listenerList) {
l.stateChanged(new WCChangeEvent(this));
}
}
public URL getURL() {
try {
return (pitem == 0 ? url : (url = newURL(bflItemGetURL(pitem))));
} catch (MalformedURLException ex) {
return url = null;
}
}
public String getTitle() {
return (pitem == 0 ? title : (title = bflItemGetTitle(pitem)));
}
public WCImage getIcon() {
return (pitem == 0 ? icon : (icon = bflItemGetIcon(pitem)));
}
public String getTarget() {
return (pitem == 0 ? target : (target = bflItemGetTarget(pitem)));
}
public Date getLastVisitedDate() {
return lastVisitedDate == null ? null : (Date)lastVisitedDate.clone();
}
private void updateLastVisitedDate() {
lastVisitedDate = new Date(System.currentTimeMillis());
notifyItemChanged();
}
public boolean isTargetItem() {
return (pitem == 0 ? isTargetItem : (isTargetItem = bflItemIsTargetItem(pitem)));
}
public Entry[] getChildren() {
return (pitem == 0 ? children : (children = bflItemGetChildren(pitem, ppage)));
}
@Override
public String toString() {
return "url=" + getURL() +
",title=" + getTitle() +
",date=" + getLastVisitedDate();
}
private final List listenerList =
new LinkedList<>();
public void addChangeListener(WCChangeListener l) {
if (l == null)
return;
listenerList.add(l);
}
public void removeChangeListener(WCChangeListener l) {
if (l == null)
return;
listenerList.remove(l);
}
}
private final WebPage page;
private final List listenerList =
new LinkedList<>();
BackForwardList(WebPage page) {
this.page = page;
// WebKit doesn't set a page's visiting date. We do it here as workaround.
// This way it works for page reload as well.
page.addLoadListenerClient(new LoadListenerClient() {
@Override public void dispatchLoadEvent(long frame,
int state,
String url,
String contentType,
double progress,
int errorCode)
{
if (state == LoadListenerClient.DOCUMENT_AVAILABLE) {
Entry entry = getCurrentEntry();
if (entry != null) {
entry.updateLastVisitedDate();
}
}
}
@Override public void dispatchResourceLoadEvent(long frame,
int state,
String url,
String contentType,
double progress,
int errorCode)
{}
});
}
public int size() {
return bflSize(page.getPage());
}
public int getMaximumSize() {
return bflGetMaximumSize(page.getPage());
}
public void setMaximumSize(int size) {
bflSetMaximumSize(page.getPage(), size);
}
public int getCurrentIndex() {
return bflGetCurrentIndex(page.getPage());
}
public boolean isEmpty() {
return size() == 0;
}
public void setEnabled(boolean flag) {
bflSetEnabled(page.getPage(), flag);
}
public boolean isEnabled() {
return bflIsEnabled(page.getPage());
}
public Entry get(int index) {
Entry host = (Entry)bflGet(page.getPage(), index);
return host;
}
public Entry getCurrentEntry() {
return get(getCurrentIndex());
}
public void clearBackForwardListForDRT() {
bflClearBackForwardListForDRT(page.getPage());
}
public int indexOf(Entry e) {
return bflIndexOf(page.getPage(), e.pitem, false);
}
public boolean contains(Entry e) {
return indexOf(e) >= 0;
}
public Entry[] toArray() {
int size = size();
Entry[] entries = new Entry[size];
for (int i = 0; i < size; i++) {
entries[i] = get(i);
}
return entries;
}
public void setCurrentIndex(int index) {
if (bflSetCurrentIndex(page.getPage(), index) < 0) {
throw new IllegalArgumentException("invalid index: " + index);
}
}
private boolean canGoBack(int index) {
return index > 0;
}
public boolean canGoBack() {
return canGoBack(getCurrentIndex());
}
public boolean goBack() {
int index = getCurrentIndex();
if (canGoBack(index)) {
setCurrentIndex(index - 1);
return true;
}
return false;
}
private boolean canGoForward(int index) {
return index < (size() - 1);
}
public boolean canGoForward() {
return canGoForward(getCurrentIndex());
}
public boolean goForward() {
int index = getCurrentIndex();
if (canGoForward(index)) {
setCurrentIndex(index + 1);
return true;
}
return false;
}
public void addChangeListener(WCChangeListener l) {
if (l == null) {
return;
}
if (listenerList.isEmpty()) {
bflSetHostObject(page.getPage(), this);
}
listenerList.add(l);
}
public void removeChangeListener(WCChangeListener l) {
if (l == null) {
return;
}
listenerList.remove(l);
if (listenerList.isEmpty()) {
bflSetHostObject(page.getPage(), null);
}
}
public WCChangeListener[] getChangeListeners() {
return listenerList.toArray(new WCChangeListener[0]);
}
// Only called from the native code.
private void notifyChanged() {
for (WCChangeListener l : listenerList) {
l.stateChanged(new WCChangeEvent(this));
}
}
native private static String bflItemGetURL(long item);
native private static String bflItemGetTitle(long item);
native private static WCImage bflItemGetIcon(long item);
native private static long bflItemGetLastVisitedDate(long item);
native private static boolean bflItemIsTargetItem(long item);
native private static Entry[] bflItemGetChildren(long item, long page);
native private static String bflItemGetTarget(long item);
native private static void bflClearBackForwardListForDRT(long page);
native private static int bflSize(long page);
native private static int bflGetMaximumSize(long page);
native private static void bflSetMaximumSize(long page, int size);
native private static int bflGetCurrentIndex(long page);
native private static int bflIndexOf(long page, long item, boolean reverse);
native private static void bflSetEnabled(long page, boolean flag);
native private static boolean bflIsEnabled(long page);
native private static Object bflGet(long page, int index);
native private static int bflSetCurrentIndex(long page, int index);
native private static void bflSetHostObject(long page, Object host);
}