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

annis.gui.widgets.gwt.client.ui.VAutoHeightIFrame Maven / Gradle / Ivy

There is a newer version: 4.0.0-beta.4
Show newest version
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