
annis.gui.widgets.gwt.client.ui.VAutoHeightIFrame Maven / Gradle / Ivy
package annis.gui.widgets.gwt.client.ui;
import annis.gui.widgets.gwt.client.ui.autoheightiframe.AutoHeightIFrameConnector;
import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.IFrameElement;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Widget;
import java.util.logging.Logger;
public class VAutoHeightIFrame extends Widget
{
private final static Logger logger = Logger.getLogger("VAutoHeightIFrame");
/**
* Set the CSS class name to allow styling.
*/
public static final String CLASSNAME = "v-autoheightiframe";
/**
* The client side widget identifier
*/
private IFrameElement iframe;
private int additionalHeight;
private AutoHeightIFrameConnector.LoadCallback callback;
/**
* The constructor should first call super() to initialize the component and
* then handle any initialization relevant to Vaadin.
*/
public VAutoHeightIFrame()
{
super();
iframe = Document.get().createIFrameElement();
iframe.setFrameBorder(0);
iframe.setScrolling("auto");
setElement(iframe);
// This method call of the Paintable interface sets the component
// style name in DOM tree
setStyleName(CLASSNAME);
addDomHandler(new LoadHandler()
{
@Override
public void onLoad(LoadEvent event)
{
if (!iframe.getSrc().endsWith("empty.html"))
{
try
{
final Document doc = iframe.getContentDocument();
if (doc != null)
{
Timer t = new Timer()
{
@Override
public void run()
{
checkIFrameLoaded(doc);
}
};
t.schedule(100);
}
}
catch (JavaScriptException ex)
{
logger.severe(
"trying to access iframe source from different domain which is forbidden");
}
}
}
}, LoadEvent.getType());
}
private void checkIFrameLoaded(Document doc)
{
int newHeight = -1;
doc.getScrollLeft();
String contentType = getContentType(doc); //doc.getDocumentElement().getPropertyString("contentType");
if (contentType != null && contentType.startsWith("image/"))
{
// image
NodeList imgList = doc.getElementsByTagName("img");
if (imgList.getLength() > 0)
{
ImageElement img = (ImageElement) imgList.getItem(0);
newHeight = img.getPropertyInt("naturalHeight");
}
}
else
{
logger.fine("body height defined?: " + doc.getBody().hasAttribute(
"scrollHeight"));
logger.fine("document height defined?: " + doc.getDocumentElement().
hasAttribute("scrollHeight"));
int bodyHeight = doc.getBody().getScrollHeight();
int documentHeight = doc.getDocumentElement().getScrollHeight();
logger.fine("body scrollHeight: " + bodyHeight
+ "document scrollHeight: " + documentHeight);
int maxHeight = Math.max(bodyHeight, documentHeight);
if (maxHeight > 20)
{
// real html page or fallback if content type is unknown (e.g. in chrome)
newHeight = maxHeight + additionalHeight;
}
}
logger.fine("newheight: " + newHeight);
if (newHeight > -1 && callback != null)
{
callback.onIFrameLoaded(newHeight);
}
}
public void setLoadCallback(AutoHeightIFrameConnector.LoadCallback callback)
{
this.callback = callback;
}
/**
* Called whenever an update is received from the server
*/
public void update(String url, int additionalHeight)
{
if (iframe.getSrc() != null && url != null && iframe.getSrc().equals(url))
{
return;
}
if (additionalHeight > -1)
{
this.additionalHeight = additionalHeight;
}
final Style style = iframe.getStyle();
style.setWidth(
100, Style.Unit.PCT);
if (url != null)
{
//VConsole.log("iframe is updated with url " + url );
iframe.setSrc(url);
}
}
public final native String getContentType(Document doc) /*-{
return doc.contentType;
}-*/;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy