Package org.gwt.mosaic.core.client

Source Code of org.gwt.mosaic.core.client.DOM

/*
* Copyright (c) 2008-2009 GWT Mosaic Georgios J. Georgopoulos
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.gwt.mosaic.core.client;

import org.gwt.mosaic.core.client.impl.DOMImpl;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.BodyElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.user.client.Element;

/**
* Provides helper methods for DOM elements.
*
* @author georgopoulos.georgios(at)gmail.com
*
*/
public class DOM extends com.google.gwt.user.client.DOM {

  private static final DOMImpl impl = GWT.create(DOMImpl.class);

  public static final int OTHER_KEY_UP = 63232;

  public static final int OTHER_KEY_DOWN = 63233;

  public static final int OTHER_KEY_LEFT = 63234;

  public static final int OTHER_KEY_RIGHT = 63235;

  private static Element toPixelSizeTestElem = null;

  /**
   * If using standards mode, and the body (i.e. RootPanel.get()) is going to be
   * your boundary panel, you'll want to ensure that the body actually has
   * height; with only absolute positioned content, the height remains 0px.
   * Usually setting 100% height on the HTML and BODY elements does the trick.
   * <p>
   * html,body { height: 100%; }
   */
  static {
    if (CompatMode.isStandardsMode()) {
      Document doc = Document.get();
      NodeList<com.google.gwt.dom.client.Element> nodeList = doc.getElementsByTagName("html");
      if (nodeList != null && nodeList.getLength() > 0) {
        Element elem = Document.get().getElementsByTagName("html").getItem(0).cast();
        elem.getStyle().setProperty("height", "100%");
      }
      BodyElement body = doc.getBody();
      body.getStyle().setProperty("height", "100%");
    }
  }

  /**
   * Fixes the box calculations for IE in QuirksMode.
   *
   * @param elem the element to set the dimension on
   * @param dim the number of the dimension to fix
   * @param side the dimension ('h' or 'w') to fix (defaults to 'h')
   * @return the fixed dimension
   */
  public static int fixQuirks(Element elem, int dim, char side) {
    int i1 = 0, i2 = 2;
    if (side == 'w') {
      i1 = 1;
      i2 = 3;
    }
    if (UserAgent.isIE6() && !CompatMode.isStandardsMode()) {
      // Internet Explorer - Quirks Mode
      int[] b = getBorderSizes(elem);
      int[] bp = getBorderSizes((Element) elem.getParentElement());
      if ((b[i1] == 0) && (b[i2] == 0)) { // No Borders, check parent
        if ((bp[i1] != 0) && (bp[i2] != 0)) { // Parent has borders
          dim -= (bp[i1] + bp[i2]);
        }
      } else {
        if ((bp[i1] == 0) && (bp[i2] == 0)) { // Parent has borders
          dim += (b[i1] + b[i2]);
        }
      }
    }
    return dim;
  }

  /**
   * Get the CSS border size of the element passed.
   *
   * @param elem the element to get the border size of
   * @return an array of the top, right, bottom, left borders
   */
  public static int[] getBorderSizes(Element elem) {
    int[] size = new int[4];

    if (UserAgent.isIE6() /* && !CompatMode.isStandardsMode() */) {
      elem.getStyle().setProperty("zoom", "1");
    }

    // IE will return NaN on these if they are set to auto, well set them to 0

    size[0] = parseInt(getComputedStyleAttribute(elem, "borderTopWidth"), 10, 0);
    size[1] = parseInt(getComputedStyleAttribute(elem, "borderRightWidth"), 10,
        0);
    size[2] = parseInt(getComputedStyleAttribute(elem, "borderBottomWidth"),
        10, 0);
    size[3] = parseInt(getComputedStyleAttribute(elem, "borderLeftWidth"), 10,
        0);

    return size;
  }

  /**
   * Get's the elements <code>clientHeight</code> and <code>clientWidth</code>
   * plus the size of the borders and margins even if {@code visibility} is set
   * to {@code false}.
   * <p>
   * https://developer.mozilla.org/en/Determining_the_dimensions_of_elements
   *
   * @param elem the element to get the size of
   * @return an array of width and height
   */
  public static Dimension getBoxSize(Element elem) {
    final int[] m = getMarginSizes(elem);
    final int[] b = getBorderSizes(elem);
    final Dimension c = getClientSize(elem);
    c.width += (b[1] + b[3]) + (m[1] + m[3]);
    c.height += (b[0] + b[2]) + (m[0] + m[2]);
    return c;
  }

  /**
   * Returns the inner height of an element in pixels, including padding but not
   * the horizontal scrollbar height, border, or margin.
   * <p>
   * <code>clientHeight</code> can be calculated as CSS height + CSS padding -
   * height of horizontal scrollbar (if present).
   * <p>
   * NOTE: Not part of any W3C specification.
   *
   * @param elem the element to get the <code>clientHeight</code> of
   * @return the <code>clientHeight</code> of the given element
   */
  private native static int getClientHeight(Element elem)
  /*-{
    return elem.clientHeight;
  }-*/;

  /**
   * Get's the elements {@code clientHeight} and {@code clientWidth}.
   * <p>
   * Both {@code clientHeight} and {@code clientWidth} are a non-standard,
   * HTML-specific property introduced in the IE object model.
   * <p>
   * https://developer.mozilla.org/en/Determining_the_dimensions_of_elements
   *
   * @param elem the element to get the size of
   * @return an array of width and height
   */
  public static Dimension getClientSize(Element elem) {
    if (UserAgent.isIE6() /* && !CompatMode.isStandardsMode() */) {
      elem.getStyle().setProperty("zoom", "1");
    }
    return new Dimension(getClientWidth(elem), getClientHeight(elem));
  }

  /**
   * Returns the inner width of an element in pixels, including padding but not
   * the horizontal scrollbar width, border, or margin.
   * <p>
   * {@code clientWidth} can be calculated as CSS width + CSS padding - width of
   * vertical scrollbar (if present).
   * <p>
   * NOTE: Not part of any W3C specification.
   *
   * @param elem the element to get the {@code clientWidth} of
   * @return the {@code clientWidth} of the given element
   */
  private native static int getClientWidth(Element elem)
  /*-{
    return elem.clientWidth;
  }-*/;

  /**
   * Gets an attribute of the given element's computed style.
   * <p>
   * http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSview-
   * getComputedStyle
   *
   * @param elem the element whose style attribute is to be retrieved
   * @param attr the name of the style attribute to be retrieved
   * @return the computed style attribute's value
   */
  public static String getComputedStyleAttribute(Element elem, String attr) {
    return impl.getComputedStyleAttribute(elem, attr);
  }

  /**
   * Get the CSS margin size of the element passed.
   *
   * @param elem the element to get the margin size of
   * @return an array of the top, right, bottom, left margins
   */
  public static int[] getMarginSizes(Element elem) {
    int[] size = new int[4];

    if (UserAgent.isIE6() /* && !CompatMode.isStandardsMode() */) {
      elem.getStyle().setProperty("zoom", "1");
    }

    // IE will return NaN on these if they are set to auto, well set them to 0

    size[0] = parseInt(getComputedStyleAttribute(elem, "marginTop"), 10, 0);
    size[1] = parseInt(getComputedStyleAttribute(elem, "marginRight"), 10, 0);
    size[2] = parseInt(getComputedStyleAttribute(elem, "marginBottom"), 10, 0);
    size[3] = parseInt(getComputedStyleAttribute(elem, "marginLeft"), 10, 0);

    return size;
  }

  public static int[] getPaddingSizes(Element elem) {
    int[] size = new int[4];

    if (UserAgent.isIE6() /* && !CompatMode.isStandardsMode() */) {
      elem.getStyle().setProperty("zoom", "1");
    }

    // IE will return NaN on these if they are set to auto, well set them to 0

    size[0] = parseInt(getComputedStyleAttribute(elem, "paddingTop"), 10, 0);
    size[1] = parseInt(getComputedStyleAttribute(elem, "paddingRight"), 10, 0);
    size[2] = parseInt(getComputedStyleAttribute(elem, "paddingBottom"), 10, 0);
    size[3] = parseInt(getComputedStyleAttribute(elem, "paddingLeft"), 10, 0);

    return size;
  }

  /**
   * Returns the screen resolution in dots-per-inch.
   *
   * @return the screen resolution, in dots-per-inch
   */
  public static int getScreenResolution() {
    return toPixelSize("1in");
  }

  public static Dimension getStringBoxSize(Element span, final String str) {
    final BodyElement body = Document.get().getBody();
    span.setInnerText(str);
    setStyleAttribute(span, "left", "");
    setStyleAttribute(span, "top", "");
    setStyleAttribute(span, "position", "absolute");
    setStyleAttribute(span, "visibility", "hidden");

    // force "auto" width
    setStyleAttribute(span, "width", "0px");
    setStyleAttribute(span, "height", "0px");

    span.getOffsetWidth();
    span.getOffsetHeight();

    setStyleAttribute(span, "width", "auto");
    setStyleAttribute(span, "height", "auto");

    try {
      body.appendChild(span);
      return getBoxSize(span);
    } finally {
      body.removeChild(span);
    }
  }

  public static boolean isVisible(Element element) {
    return !"none".equalsIgnoreCase(DOM.getComputedStyleAttribute(element,
        "display"));
  }

  /**
   * Parses a string and returns an integer.
   * <p>
   * NOTE: Only the first number in the string is returned!
   * <p>
   * NOTE: Leading and trailing spaces are allowed.
   * <p>
   * NOTE: If the first character cannot be converted to a number,
   * <code>parseInt()</code> returns <code>null</code>.
   *
   * @param str the string to be parsed
   * @return the parsed value
   */
  protected static Integer parseInt(String str) {
    return parseInt(str, 10);
  }

  /**
   * Parses a string and returns an integer.
   * <p>
   * NOTE: Only the first number in the string is returned!
   * <p>
   * NOTE: Leading and trailing spaces are allowed.
   * <p>
   * NOTE: If the first character cannot be converted to a number,
   * <code>parseInt()</code> returns <code>null</code>.
   *
   * @param str the string to be parsed
   * @param radix a number (from 2 to 36) that represents the numeric system to
   *          be used
   * @return the parsed value
   */
  protected native static Integer parseInt(String str, int radix)
  /*-{
    var number = parseInt(str, radix);
    if (isNaN(number))
      return null;
    else
      return @java.lang.Integer::valueOf(I)(number);
  }-*/;

  /**
   * Parses a string and returns an integer.
   * <p>
   * NOTE: Only the first number in the string is returned!
   * <p>
   * NOTE: Leading and trailing spaces are allowed.
   * <p>
   * NOTE: If the first character cannot be converted to a number,
   * <code>parseInt()</code> returns <code>null</code>.
   *
   * @param str the string to be parsed
   * @param radix a number (from 2 to 36) that represents the numeric system to
   *          be used
   * @param defaultValue the value to return if the parsed value was
   *          <code>null</code>
   * @return the parsed value
   */
  private static int parseInt(String str, int radix, int defaultValue) {
    final Integer result = parseInt(str, radix);
    return result == null ? defaultValue : result;
  }

  /**
   * Sets an attribute on the given element's style.
   *
   * @param elem the element whose style attribute is to be set
   * @param attr the name of the style attribute to be set
   * @param value the style attribute's new value
   */
  public static void setStyleAttribute(Element elem, String attr, String value) {
    try {
      impl.setStyleAttribute(elem, attr, value);
    } catch (Exception ex) {
      GWT.log("Set style attribute error, tag=" + elem.getTagName() + ", attr="
          + attr + ", value=" + value, ex);
    }
  }

  public static int toPixelSize(final String width) {
    if (toPixelSizeTestElem == null) {
      toPixelSizeTestElem = DOM.createSpan();
      setStyleAttribute(toPixelSizeTestElem, "left", "");
      setStyleAttribute(toPixelSizeTestElem, "top", "");
      setStyleAttribute(toPixelSizeTestElem, "position", "absolute"); // Safari
      setStyleAttribute(toPixelSizeTestElem, "visibility", "hidden");
      Document.get().getBody().appendChild(toPixelSizeTestElem);
    }
    setStyleAttribute(toPixelSizeTestElem, "width", width);
    return getBoxSize(toPixelSizeTestElem).width;
  }

}
TOP

Related Classes of org.gwt.mosaic.core.client.DOM

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.