Results 1 to 7 of 7

Thread: XElement.isOrHasChild(XElement)

    Success! Looks like we've fixed this one. According to our records the fix was applied for EXTGWT-4675 in 4.0.1.
  1. #1
    Sencha User
    Join Date
    Dec 2015
    Posts
    6

    Default XElement.isOrHasChild(XElement)

    Hi,
    i use gxt 4.0 trial and gwt 2.7
    what is the cause of this problem?


    com.google.gwt.user.client.Element$.isOrHasChild$(Lcom/google/gwt/user/client/Element;Lcom/google/gwt/dom/client/NodeZ: java.lang.NoSuchMethodError: com.google.gwt.user.client.Element$.isOrHasChild$(Lcom/google/gwt/user/client/Element;Lcom/google/gwt/dom/client/NodeZ

  2. #2
    Sencha Sr Product Manager
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    1,165

    Default

    Thanks for reporting this is a bug. Although can you tell me how you are getting it? So far this has been reported in a Window with a datepicker.

  3. #3
    Sencha Sr Product Manager
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    1,165

    Default

    Update... There is a fix getting reviewed for this issue. Turns out it can happen in classic dev mode in several places. To work around it at the moment super dev mode can be used. The engineers out for the holidays so it may be slow to get back for a couple weeks.

  4. #4
    Sencha User
    Join Date
    Dec 2015
    Posts
    6

    Default

    I tried it in production and all seems ok

  5. #5
    Sencha Premium Member
    Join Date
    Oct 2009
    Posts
    112

    Default

    Also getting this error in just about all messagebox windows in my app.

    Work as expected in super dev mode and production...would be nice to have a fix soon.

  6. #6
    Sencha Sr Product Manager
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    1,165

    Default

    The fix has been finished and is in 4.0.1. The minor release should be out middle sometime in March. In the meantime if you want a workaround, the XElement can be masked. Let me know if you want the copy of the XElement class with the workaround?

  7. #7
    Sencha Sr Product Manager
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    1,165

    Default

    This has been fixed in 4.0.1 which will be released soon. In the meantime, I've got a workaround. The workaround means you have to mask the current sdk XElement java class with a copy.

    Add this with the same package name to your source folder. This has the fix that will work with classic dev mode.
    Code:
    package com.sencha.gxt.core.client.dom;
    
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    
    import com.google.gwt.core.client.GWT;
    import com.google.gwt.core.client.JavaScriptException;
    import com.google.gwt.core.client.Scheduler;
    import com.google.gwt.core.client.Scheduler.ScheduledCommand;
    import com.google.gwt.dom.client.Document;
    import com.google.gwt.dom.client.Element;
    import com.google.gwt.dom.client.Node;
    import com.google.gwt.dom.client.NodeList;
    import com.google.gwt.dom.client.Style.Display;
    import com.google.gwt.dom.client.Style.Overflow;
    import com.google.gwt.dom.client.Style.Position;
    import com.google.gwt.dom.client.Style.Unit;
    import com.google.gwt.dom.client.Style.Visibility;
    import com.google.gwt.http.client.Request;
    import com.google.gwt.http.client.RequestBuilder;
    import com.google.gwt.http.client.RequestCallback;
    import com.google.gwt.http.client.Response;
    import com.google.gwt.regexp.shared.RegExp;
    import com.google.gwt.safehtml.shared.SafeHtml;
    import com.google.gwt.safehtml.shared.SafeHtmlUtils;
    import com.google.gwt.user.client.DOM;
    import com.sencha.gxt.core.client.GXT;
    import com.sencha.gxt.core.client.Style;
    import com.sencha.gxt.core.client.Style.Anchor;
    import com.sencha.gxt.core.client.Style.AnchorAlignment;
    import com.sencha.gxt.core.client.Style.ScrollDirection;
    import com.sencha.gxt.core.client.Style.Side;
    import com.sencha.gxt.core.client.dom.impl.ComputedStyleImpl;
    import com.sencha.gxt.core.client.resources.CommonStyles;
    import com.sencha.gxt.core.client.resources.ThemeStyles;
    import com.sencha.gxt.core.client.util.Margins;
    import com.sencha.gxt.core.client.util.Padding;
    import com.sencha.gxt.core.client.util.Point;
    import com.sencha.gxt.core.client.util.Rectangle;
    import com.sencha.gxt.core.client.util.Region;
    import com.sencha.gxt.core.client.util.Scroll;
    import com.sencha.gxt.core.client.util.Size;
    import com.sencha.gxt.core.client.util.TextMetrics;
    import com.sencha.gxt.core.client.util.Util;
    import com.sencha.gxt.core.shared.FastMap;
    
    
    /**
     * <p>Adds additional features and functionality to the GWT <code>Element</code> class.</p>
     * <p>XElement's cannot be directly instantiated. New XElements can be created using the static
     * {@link #createElement(String)} method.</p>
     */
    @SuppressWarnings("deprecation")
    public class XElement extends com.google.gwt.user.client.Element {
    
    
      /**
       * VisMode enumeration. Specifies the the element should hidden using the CSS display or visibility style.
       * 
       * @see #setVisible(boolean)
       */
      public enum VisMode {
        DISPLAY, VISIBILITY
      }
    
    
      /**
       * Workaround for http://code.google.com/p/google-web-toolkit/issues/detail?id=3192, breaking the XElement static
       * fields into their own class so they can be created, accessed through a 'real' Java type, not a JSO.
       */
      private static class FieldHolder {
        private static Map<String, Boolean> borderBoxMap = new FastMap<Boolean>();
    
    
        private static ComputedStyleImpl computedStyle = GWT.create(ComputedStyleImpl.class);
    
    
        private static int adjustXYOffset;
    
    
        private static RegExp leftOrRight = RegExp.compile("Left|Right");
    
    
        static {
          XElement elem = XElement.createElement("div");
          elem.setXY(100, 100);
    
    
          Document.get().getBody().appendChild(elem);
    
    
          Point p = elem.getXY();
          if (p.getX() != 100) {
            adjustXYOffset = p.getX() - 100;
          }
    
    
          elem.removeFromParent();
        }
      }
    
    
      /**
       * Tests to see if the value has units, otherwise appends the default (px).
       * 
       * @param v the value
       * @param defaultUnit the default unit to use, or px if not specified
       * @return the value with units
       */
      public native static String addUnits(String v, String defaultUnit) /*-{
        if (v === "" || v == "auto") {
            return v;
        }
        if (v === undefined) {
            return '';
        }
        if (typeof v == "number"
                || !/\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i.test(v)) {
            return v + (defaultUnit || 'px');
        }
        return v;
      }-*/;
    
    
      /**
       * Assert that the given {@link Node} is an {@link Element} and automatically typecast it.
       *
       * @param node the node to be typecast
       * @return the node typecast as an element
       */
      public static XElement as(Node node) {
        assert Element.is(node);
        return (XElement) node;
      }
    
    
      /**
       * Creates a new element based on the specified HTML tag name.
       * 
       * @param tagName the element tag name
       * @return the new element
       */
      public static final XElement createElement(String tagName) {
        return (XElement) Document.get().createElement(tagName);
      }
    
    
      /**
       * Returns true if the passed element has a border box.
       * 
       * @param element the element to test
       * @return true if the passed element has a border box
       */
      public static boolean isBorderBox(Element element) {
        assert element != null : "Element may not be null";
        String tag = element.getTagName().toLowerCase();
        Boolean r = FieldHolder.borderBoxMap.get(tag);
        if (r == null) {
          Element testElement = (Element) Document.get().createElement(tag);
          testElement.getStyle().setPropertyPx("padding", 1);
          testElement.getStyle().setPropertyPx("width", 100);
          testElement.getStyle().setProperty("visibility", "hidden");
          testElement.getStyle().setProperty("position", "absolute");
          Document.get().getBody().appendChild(testElement);
          r = testElement.getOffsetWidth() == 100;
          Document.get().getBody().removeChild(testElement);
          FieldHolder.borderBoxMap.put(tag, r);
        }
        return r;
      }
    
    
      private native static void disableTextSelectInternal(Element e, boolean disable) /*-{
        if (disable) {
            e.ondrag = function(evt) {
                var targ;
                if (!evt)
                    evt = $wnd.event;
                if (evt.target)
                    targ = evt.target;
                else if (evt.srcElement)
                    targ = evt.srcElement;
                if (targ.nodeType == 3) // defeat Safari bug
                    targ = targ.parentNode;
                if (targ.tagName == 'INPUT' || targ.tagName == 'TEXTAREA') {
                    return true;
                }
                return false;
            }
            e.onselectstart = function(evt) {
                var targ;
                if (!evt)
                    evt = $wnd.event;
                if (evt.target)
                    targ = evt.target;
                else if (evt.srcElement)
                    targ = evt.srcElement;
                if (targ.nodeType == 3) // defeat Safari bug
                    targ = targ.parentNode;
                if (targ.tagName == 'INPUT' || targ.tagName == 'TEXTAREA') {
                    return true;
                }
                return false;
            };
        } else {
            e.ondrag = null;
            e.onselectstart = null;
        }
      }-*/;
    
    
      /**
       * Not directly instantiable. Subclasses should also define a protected no-arg constructor to prevent client code from
       * directly instantiating the class.
       */
      protected XElement() {
      }
    
    
      /**
       * Adds the style names to the element. Duplicate styles are automatically filtered out.
       * 
       * @param classNames the new class names to add
       */
      public final void addClassName(String... classNames) {
        if (classNames != null) {
          for (String styleName : classNames) {
            if (styleName != null && !hasClassName(styleName)) {
              styleName = styleName.trim();
              setClassName(getClassName() + " " + styleName);
            }
          }
        }
      }
    
    
      /**
       * Adds the style names to the element. Duplicate styles are automatically filtered out.
       * 
       * @param className1 the first new class name to add
       * @param className2 the second new class name to add
       */
      public final void addClassName(String className1, String className2) {
        addClassName(className1);
        addClassName(className2);
      }
    
    
      /**
       * Adds the event type to the element's sunk events.
       * 
       * @param event the events to add
       */
      public final void addEventsSunk(int event) {
        int bits = DOM.getEventsSunk((Element) this.cast());
        DOM.sinkEvents((Element) this.cast(), bits | event);
      }
    
    
      /**
       * Ensures the entire element fits within the browser viewport.
       * The target point (x, y) will be adjusted inward until it fits.
       * This may result in a different position, but the size will
       * stay the same.
       * 
       * @param point the target point
       * @return the adjusted point
       */
      public final Point adjustForConstraints(Point point) {
        return adjustForConstraints(Document.get().getBody(), point);
      }
    
    
      /**
       * Ensures the entire element fits within the constraining element.
       * This may result in a different position, but the size will
       * stay the same.
       *
       * @param constraint the element to constrain within
       * @param point the target point
       * @return the adjusted point
       */
      public final Point adjustForConstraints(Element constraint, Point point) {
        // possibly move logic here and deprecate protected method
        return getConstrainToXY(constraint, point);
      }
    
    
      /**
       * Ensures the entire element fits within the browser viewport.
       * The target bounds (x, y, width, height) will be adjusted inward
       * until it fits. This may result in a both a different position
       * and a different size.
       *
       * @param bounds the target bounds
       * @return the adjusted bounds
       */
      public final Rectangle adjustForConstraints(Rectangle bounds) {
        return adjustForConstraints(Document.get().getBody(), bounds);
      }
    
    
      /**
       * Ensures the entire element fits within the constraining element.
       * The target bounds (x, y, width, height) will be adjusted inward
       * until it fits. This may result in a both a different position
       * and a different size.
       *
       * @param constraint the element to constrain within
       * @param bounds the target bounds
       * @return the adjusted bounds
       */
      public final Rectangle adjustForConstraints(Element constraint, Rectangle bounds) {
        int constraintTop = 0;
        int constraintRight = 0;
        int constraintBottom = 0;
        int constraintLeft = 0;
        if (constraint == Document.get().getBody()) {
          constraintRight = XDOM.getViewportSize().getWidth();
          constraintBottom = XDOM.getViewportSize().getHeight();
        } else {
          constraintTop = constraint.getAbsoluteTop();
          constraintRight = constraint.getAbsoluteLeft() + constraint.getOffsetWidth();
          constraintBottom = constraint.getAbsoluteTop() + constraint.getOffsetHeight();
          constraintLeft = constraint.getAbsoluteLeft();
        }
    
    
        int boundsTop = bounds.getY();
        int boundsRight = bounds.getX() + bounds.getWidth();
        int boundsBottom = bounds.getY() + bounds.getHeight();
        int boundsLeft = bounds.getX();
    
    
    
    
        if (boundsTop < constraintTop) {
          boundsTop = constraintTop;
        }
        if (boundsRight > constraintRight) {
          boundsRight = constraintRight;
        }
        if (boundsBottom > constraintBottom) {
          boundsBottom = constraintBottom;
        }
        if (boundsLeft < constraintLeft) {
          boundsLeft = constraintLeft;
        }
    
    
        return new Rectangle(boundsLeft, boundsTop, (boundsRight - boundsLeft), (boundsBottom - boundsTop));
      }
    
    
      /**
       * Aligns the element with another element relative to the specified anchor points.
       * 
       * @param elem the element to align to
       * @param alignment the position to align to
       * @param offsetX X offset
       * @param offsetY Y offset
       */
      public final void alignTo(Element elem, AnchorAlignment alignment, int offsetX, int offsetY) {
        Point p = getAlignToXY(elem, alignment, offsetX, offsetY);
        setXY(p);
      }
    
    
      /**
       * Sets multiple style properties. Style attribute names must be in lower camel case, e.g.
       * "backgroundColor:white; color:red;"
       * 
       * @param styles a style specification string
       */
      public final native void applyStyles(String styles) /*-{
        var re = /\s?([a-z\-]*)\:\s?([^;]*);?/gi;
        var matches;
        while ((matches = re.exec(styles)) != null) {
            this.style[matches[1]] = matches[2];
        }
      }-*/;
    
    
      /**
       * Centers the element in the viewport.
       */
      public final void center() {
        center(null);
      }
    
    
      /**
       * Centers the element.
       * 
       * @param constrainViewport true to constrain the element position to the viewport.
       */
      public final void center(boolean constrainViewport) {
        alignTo(Document.get().getBody(), new AnchorAlignment(Anchor.CENTER, Anchor.CENTER, constrainViewport), 0, 0);
      }
    
    
      /**
       * Centers an element.
       * 
       * @param container the container element
       */
      public final void center(Element container) {
        if (container == null) {
          container = Document.get().getBody();
        }
        alignTo(container, new AnchorAlignment(Anchor.CENTER, Anchor.CENTER, false), 0, 0);
      }
    
    
      /**
       * Selects a single child at any depth below this element based on the passed CSS selector.
       * 
       * @param selector the css selector
       * @return the child element
       */
      public final XElement child(String selector) {
        Element child = childElement(selector);
        return child == null ? null : XElement.as(child);
      }
    
    
      /**
       * Selects a single child at any depth below this element based on the passed CSS selector.
       * 
       * @param selector the css selector
       * @return the child element
       */
      public final Element childElement(String selector) {
        return DomQuery.selectNode(selector, this);
      }
    
    
      /**
       * Generators a native dom click on the element.
       */
      public final native void click() /*-{
        var dom = this;
        if (dom.click) {
            dom.click();
        } else {
            var event = $doc.createEvent("MouseEvents");
            event.initEvent('click', true, true, $wnd, 0, 0, 0, 0, 0, false,
                    false, false, false, 1, dom);
            dom.dispatchEvent(event);
        }
      }-*/;
    
    
      /**
       * Creates and adds a child using the HTML fragment.
       *
       * @param html the html fragment
       * @return the new child
       */
      public final XElement createChild(SafeHtml html) {
        return appendChild(XDOM.create(html)).<XElement> cast();
      }
    
    
      /**
       * Disables the element.
       */
      public final void disable() {
        setPropertyBoolean("disabled", true);
      }
    
    
      /**
       * Enables or disables text selection for the element and all children. A circular reference will be created when disabling text
       * selection. Disabling should be cleared when the element is detached. See the <code>Component</code> source for an
       * example.
       * 
       * @param disable true to disable, false to enable
       */
      public final void disableTextSelection(boolean disable) {
        setClassName(CommonStyles.get().unselectable(), disable);
        setPropertyString("unselectable", disable ? "on" : "");
        disableTextSelectInternal(this, disable);
      }
    
    
      /**
       * Enables or disables text selection for the element. A circular reference will be created when disabling text
       * selection. Disabling should be cleared when the element is detached. See the <code>Component</code> source for an
       * example.
       *
       * @param disable true to disable, false to enable
       */
      public final void disableTextSelectionSingle(boolean disable) {
        setClassName(CommonStyles.get().unselectableSingle(), disable);
        setPropertyString("unselectable", disable ? "on" : "");
        disableTextSelectInternal(this, disable);
      }
    
    
      /**
       * Selects a single *direct* child based on the passed CSS selector (the selector should not contain an id).
       * 
       * @param selector the CSS selector
       * @return the child element
       */
      public final XElement down(String selector) {
        Element elem = DomQuery.selectNode(" > " + selector, this);
        if (elem != null) {
          return XElement.as(elem);
        }
        return null;
      }
    
    
      /**
       * Enables the element.
       */
      public final void enable() {
        setPropertyBoolean("disabled", false);
      }
    
    
      /**
       * Walks up the DOM and ensures all elements are visible. Useful when trying to calculate offsets or page coordinates.
       * 
       * @return list of meta data, see {@link #restoreVisible(List)}
       */
      public final List<FastMap<Object>> ensureVisible() {
        List<FastMap<Object>> list = new ArrayList<FastMap<Object>>();
        XElement p = this;
        XElement body = Document.get().getBody().cast();
        while (p != null && p != body) {
          if (p.isStyleAttribute("display", "none")) {
            FastMap<Object> m = new FastMap<Object>();
            m.put("element", p);
            m.put("origd", p.getStyle().getProperty("display"));
    
    
            boolean hasxhideoffset = p.hasClassName(CommonStyles.get().hideOffsets());
            m.put("hasxhideoffset", hasxhideoffset);
            if (!hasxhideoffset) {
              p.addClassName(CommonStyles.get().hideOffsets());
            }
    
    
            boolean hideDisplay = p.hasClassName(CommonStyles.get().hideDisplay());
            if (hideDisplay) {
              m.put("hasxhidedisplay", hideDisplay);
              p.removeClassName(CommonStyles.get().hideDisplay());
            }
    
    
            p.getStyle().setProperty("display", "block");
            list.add(m);
          }
          p = (XElement) p.getParentElement();
        }
        return list.size() > 0 ? list : null;
      }
    
    
      /**
       * Looks at this node and then at parent nodes for a match of the passed simple selector (e.g. div.some-class or
       * span:first-child).
       * 
       * @param selector the simple selector to test
       * @param maxDepth the max depth
       * @return the matching element
       */
      public final XElement findParent(String selector, int maxDepth) {
        Element elem = findParentElement(selector, maxDepth);
        if (elem == null) {
          return null;
        }
        return XElement.as(elem);
      }
    
    
      /**
       * Looks at this node and then at parent nodes for a match of the passed simple selector (e.g. div.some-class or
       * span:first-child).
       * 
       * @param selector the simple selector to test
       * @param maxDepth the max depth
       * @return the matching element
       */
      public final Element findParentElement(String selector, int maxDepth) {
        Element p = this;
        Element b = Document.get().getBody();
        int depth = 0;
        while (p != null && p.getNodeType() == 1 && (maxDepth == -1 || depth < maxDepth) && p != b) {
          if (DomQuery.is(p, selector)) {
            return p;
          }
          depth++;
          p = (Element) p.getParentElement();
        }
        return null;
      }
    
    
      /**
       * Gets the x,y coordinates to align this element with another element.
       * 
       * @param elem the element to align to
       * @param alignment the alignment
       * @param ox x offset
       * @param oy y offset
       * @return the point
       */
      public final Point getAlignToXY(Element elem, AnchorAlignment alignment, int ox, int oy) {
        XElement el = XElement.as(elem);
    
    
        boolean constrainViewport = alignment.isConstrainViewport();
        Anchor anch1 = alignment.getAlign();
        Anchor anch2 = alignment.getTargetAlign();
        // Subtract the aligned el's internal xy from the target's offset xy
        // plus custom offset to get the aligned el's new offset xy
        Point a1 = getAnchorXY(anch1, true);
        Point a2 = el.getAnchorXY(anch2, false);
    
    
        int x = a2.getX() - a1.getX() + ox;
        int y = a2.getY() - a1.getY() + oy;
    
    
        if (constrainViewport) {
          // constrain the aligned el to viewport if necessary
          int w = getOffsetWidth();
          int h = getOffsetHeight();
          Region r = el.getRegion();
          int dw = XDOM.getViewWidth(false);
          int dh = XDOM.getViewHeight(false);
    
    
          // If we are at a viewport boundary and the aligned el is anchored on a
          // target border that is
          // perpendicular to the vp border, allow the aligned el to slide on that
          // border,
          // otherwise swap the aligned el to the opposite border of the target.
          boolean swapY = (anch1.isTop() && anch2.isBottom()) || (anch1.isBottom() && anch2.isTop());
          boolean swapX = (anch1.isRight() && anch2.isLeft()) || (anch1.isLeft() && anch2.isRight());
    
    
          // EXTGWT-1730 only applying 5 when there is scrolling. 5 may be able to
          // be removed
          // but not sure why this was added in first place. it exists in 2.0
          int scrollX = XDOM.getBodyScrollLeft();
    
    
          if (scrollX > 0) {
            scrollX += 5;
          }
          int scrollY = XDOM.getBodyScrollTop();
          if (scrollY > 0) {
            scrollY += 5;
          }
    
    
          if ((x + w) > dw + scrollX) {
            x = swapX ? r.getLeft() - w : dw + scrollX - w;
          }
          if (x < scrollX) {
            x = swapX ? r.getRight() : scrollX;
          }
    
    
          if ((y + h) > (dh + scrollY)) {
            y = swapY ? r.getTop() - h : dh + scrollY - h;
          }
          if (y < scrollY) {
            y = swapY ? r.getBottom() : scrollY;
          }
        }
    
    
        return new Point(x, y);
      }
    
    
      /**
       * Returns the x,y coordinates specified by the anchor position on the element.
       * 
       * @param anchor the specified anchor position (defaults to {@code CENTER}). See {@link #alignTo} for details on
       *          supported anchor positions.
       * @param local {@code true} to get the local (element top/left-relative) anchor position instead of page coordinates
       * @return the position
       */
      public final Point getAnchorXY(Anchor anchor, boolean local) {
        if (anchor == null) {
          return null;
        }
        boolean vp = false;
        final int w;
        final int h;
        if (this.cast() == Document.get().getBody() || this == Document.get().getDocumentElement()) {
          vp = true;
          w = XDOM.getViewWidth(false);
          h = XDOM.getViewHeight(false);
        } else {
          w = getOffsetWidth();
          h = getOffsetHeight();
        }
    
    
        int x = 0, y = 0;
        switch (anchor) {
          case CENTER:
            x = (int) Math.round(w * .5);
            y = (int) Math.round(h * .5);
            break;
          case TOP:
            x = (int) Math.round(w * .5);
            y = 0;
            break;
          case LEFT:
            x = 0;
            y = (int) Math.round(h * .5);
            break;
          case RIGHT:
            x = w;
            y = (int) Math.round(h * .5);
            break;
          case BOTTOM:
            x = (int) Math.round(w * .5);
            y = h;
            break;
          case TOP_LEFT:
            x = 0;
            y = 0;
            break;
          case BOTTOM_LEFT:
            x = 0;
            y = h;
            break;
          case BOTTOM_RIGHT:
            x = w;
            y = h;
            break;
          case TOP_RIGHT:
            x = w;
            y = 0;
            break;
        }
    
    
        if (local) {
          return new Point(x, y);
        }
        if (vp) {
          Scroll sc = getScroll();
          return new Point(x + sc.getScrollLeft(), y + sc.getScrollTop());
        }
        // Add the element's offset xy
    
    
        Point o = getXY();
        return new Point(x + o.getX(), y + o.getY());
      }
    
    
      /**
       * <p>Returns the total border size of the specified sides.</p>
       * <p>Passing more than one side will yield the sum of the sides of those sides of the element.</p>
       * @param side the side
       * @return the sum of the widths of the borders
       */
      public final int getBorders(Side side) {
        switch (side) {
          case LEFT:
            return Util.parseInt(getComputedStyle("borderLeft"), 0);
          case RIGHT:
            return Util.parseInt(getComputedStyle("borderRight"), 0);
          case TOP:
            return Util.parseInt(getComputedStyle("borderTop"), 0);
          case BOTTOM:
            return Util.parseInt(getComputedStyle("borderBottom"), 0);
        }
        assert false : "Unparsable Side " + side;
        return 0;
      }
    
    
      /**
       * <p>Returns the total border size of the specified sides.</p>
       * <p>Passing more than one side will yield the sum of the sides of those sides of the element.</p>
       * 
       * @param sides the sides
       * @return the sum of the widths of the borders
       */
      public final int getBorders(Side... sides) {
        List<String> list = new ArrayList<String>();
    
    
        for (int i = 0; i < sides.length; i++) {
          Side side = sides[i];
          appendSideToList(list, side, "border");
        }
    
    
        return getStylePropertyTotal(list);
      }
    
    
      /**
       * <p>Returns the total border size of the specified sides.</p>
       * <p>Passing more than one side will yield the sum of the sides of those sides of the element.</p>
       * 
       * @param side1 the first side
       * @param side2 the second side
       * @return the sum of the widths of the borders
       */
      public final int getBorders(Side side1, Side side2) {
        List<String> list = new ArrayList<String>();
    
    
        appendSideToList(list, side1, "border");
        appendSideToList(list, side2, "border");
    
    
        return getStylePropertyTotal(list);
      }
    
    
      /**
       * Returns the elements bounds in page coordinates.
       * 
       * @return the bounds
       */
      public final Rectangle getBounds() {
        return getBounds(false, false);
      }
    
    
      /**
       * Returns the elements bounds in page coordinates.
       * 
       * @param local if true the element's left and top are returned instead of page coordinates
       * 
       * @return the bounds
       */
      public final Rectangle getBounds(boolean local) {
        return getBounds(local, false);
      }
    
    
      /**
       * Returns the element's bounds in page coordinates.
       * 
       * @param local if true the element's left and top are returned instead of page coordinates
       * @param adjust if true sizes get adjusted
       * 
       * @return the element's bounds
       */
      public final Rectangle getBounds(boolean local, boolean adjust) {
        Size s = getSize(adjust);
        Rectangle rect = new Rectangle();
        rect.setWidth(s.getWidth());
        rect.setHeight(s.getHeight());
        if (local) {
          rect.setX(getLeft(true));
          rect.setY(getTop(true));
        } else {
          Point p = getXY();
          rect.setX(p.getX());
          rect.setY(p.getY());
        }
        return rect;
      }
    
    
      /**
       * Returns the index of the child element.
       *
       * @param child the child element
       * @return the index
       */
      public final int getChildIndex(Element child) {
        return DOM.getChildIndex((Element) this.cast(), (Element) child.cast());
      }
    
    
      /**
       * Returns either the offsetHeight or the height of this element based on it's CSS height.
       * 
       * @return the height
       */
      public final int getComputedHeight() {
        int h = getOffsetHeight();
        if (h == 0) {
          h = getStyleSize().getHeight();
        }
        return h;
      }
    
    
      /**
       * Returns a map of style values mapped by property name.
       * 
       * @param props the list of CSS property names
       * @return the map of property and values
       */
      public final FastMap<String> getComputedStyle(List<String> props) {
        return FieldHolder.computedStyle.getStyleAttribute(this, props);
      }
    
    
      /**
       * Normalizes currentStyle and computedStyle.
       * 
       * @param prop the style attribute whose value is returned.
       * @return the current value of the style attribute for this element.
       */
      public final String getComputedStyle(String prop) {
        return FieldHolder.computedStyle.getStyleAttribute(this, prop);
      }
    
    
      /**
       * Returns either the offsetWidth or the width of this element based on it's CSS width.
       * 
       * @return the width
       */
      public final int getComputedWidth() {
        int w = getOffsetWidth();
        if (w == 0) {
          w = getStyleSize().getWidth();
        }
        return w;
      }
    
    
      /**
       * Returns the sum width of the padding and borders for all "sides". See #getBorderWidth() for more information about
       * the sides.
       * 
       * @return the frame size
       */
      public final Size getFrameSize() {
        int width = 0;
        int height = 0;
        List<String> list = new ArrayList<String>();
        list.add("paddingLeft");
        list.add("borderLeftWidth");
    
    
        list.add("paddingRight");
        list.add("borderRightWidth");
    
    
        list.add("paddingTop");
        list.add("borderTopWidth");
    
    
        list.add("paddingBottom");
        list.add("borderBottomWidth");
    
    
        FastMap<String> map = getComputedStyle(list);
        for (String s : map.keySet()) {
          if (isLeftOrRight(s)) {
            width += Util.parseInt(map.get(s), 0);
          } else {
            height += Util.parseInt(map.get(s), 0);
          }
        }
        return new Size(width, height);
      }
    
    
      /**
       * Returns the sum width of the padding and borders for the passed "sides".
       * 
       * @param side the sides
       * @return the width
       */
      public final int getFrameWidth(Side... side) {
        List<String> list = new ArrayList<String>();
    
    
        for (int i = 0; i < side.length; i++) {
          Side s = side[i];
          appendSideToList(list, s, "padding");
          appendSideToList(list, s, "border");
        }
    
    
        return getStylePropertyTotal(list);
      }
    
    
      /**
       * Returns the sum width of the padding and borders for the given side.
       * 
       * @param side the side
       * @return the total width
       */
      public final int getFrameWidth(Side side) {
        List<String> list = new ArrayList<String>();
    
    
        appendSideToList(list, side, "padding");
        appendSideToList(list, side, "border");
        return getStylePropertyTotal(list);
      }
    
    
      /**
       * Returns the sum width of the padding and borders for the given side.
       * 
       * @param side1 the side
       * @param side2 the side
       * @return the total width
       */
      public final int getFrameWidth(Side side1, Side side2) {
        List<String> list = new ArrayList<String>();
    
    
        appendSideToList(list, side1, "padding");
        appendSideToList(list, side1, "border");
        appendSideToList(list, side2, "padding");
        appendSideToList(list, side2, "border");
    
    
        return getStylePropertyTotal(list);
      }
    
    
      /**
       * Returns the element's height.
       * 
       * @param content true to get the height minus borders and padding
       * @return the element's height
       */
      public final int getHeight(boolean content) {
        int h = getOffsetHeight();
        if (content) {
          h -= getFrameWidth(Side.TOP, Side.BOTTOM);
        }
        return Math.max(0, h);
      }
    
    
      /**
       * Returns the element's id.
       * 
       * @param autoGenId true to set an id if one does not exist
       * @return the id
       */
      public final String getId(boolean autoGenId) {
        String id = getId();
        if (!autoGenId || !(id == null || (id.length() == 0))) {
          return id;
        }
    
    
        id = DomIdProvider.generateId(this);
        setId(id);
        return id;
      }
    
    
      /**
       * Returns the top Y coordinate.
       * 
       * @return the top value
       */
      public final int getLeft() {
        return getLeft(true);
      }
    
    
      /**
       * Gets the left X coordinate.
       * 
       * @param local true to get the local css position instead of page coordinate
       * @return the left value
       */
      public final int getLeft(boolean local) {
        return local ? Util.parseInt(getStyle().getLeft(), 0) : getX();
      }
    
    
      /**
       * Returns the total margin size of the specified side.
       * 
       * @param side the side from which to calculate the margin.
       * @return the widths of the margin
       */
      public final int getMargins(Side side) {
        switch (side) {
          case LEFT:
            return Util.parseInt(getComputedStyle("marginLeft"), 0);
          case RIGHT:
            return Util.parseInt(getComputedStyle("marginRight"), 0);
          case TOP:
            return Util.parseInt(getComputedStyle("marginTop"), 0);
          case BOTTOM:
            return Util.parseInt(getComputedStyle("marginBottom"), 0);
        }
        assert false : "Unparsable Side " + side;
        return 0;
      }
    
    
      /**
       * Returns the total margin size of the specified sides.
       * 
       * @param sides the sides from which to calculate the margin. Passing more than one side will yield the sum of the
       *          margins of those sides of the element.
       * @return the sum of the widths of the margins
       */
      public final int getMargins(Side... sides) {
        List<String> list = new ArrayList<String>();
        for (Side side : sides) {
          appendSideToList(list, side, "margin");
        }
    
    
        return getStylePropertyTotal(list);
      }
    
    
      /**
       * <p>Returns the total margin size of the specified sides.</p>
       * <p>Passing more than one side will yield the sum of the margins of those sides of the element.</p>
       * 
       * @param side1 the first side from which to calculate the margin.
       * @param side2 the second side from which to calculate the margin.
       * @return the sum of the widths of the margins
       */
      public final int getMargins(Side side1, Side side2) {
        List<String> list = new ArrayList<String>();
    
    
        appendSideToList(list, side1, "margin");
        appendSideToList(list, side2, "margin");
    
    
        return getStylePropertyTotal(list);
      }
    
    
      /**
       * Returns the offsets between two elements. Both element must be part of the DOM tree and not have display:none to
       * have page coordinates.
       * 
       * @param to the to element
       * @return the xy page offsets
       */
      public final Point getOffsetsTo(Element to) {
        Point o = getXY();
    
    
        XElement xto = (XElement) to;
        Point e = xto.getXY();
        return new Point(o.getX() - e.getX(), o.getY() - e.getY());
      }
    
    
      /**
       * Returns the width of the padding(s) for the specified side.
       * 
       * @param side the side from which to calculate the padding.
       * @return the sum of the widths of the padding
       */
      public final int getPadding(Side side) {
        switch (side) {
          case LEFT:
            return Util.parseInt(getComputedStyle("paddingLeft"), 0);
          case RIGHT:
            return Util.parseInt(getComputedStyle("paddingRight"), 0);
          case TOP:
            return Util.parseInt(getComputedStyle("paddingTop"), 0);
          case BOTTOM:
            return Util.parseInt(getComputedStyle("paddingBottom"), 0);
        }
        assert false : "Unparsable Side " + side;
        return 0;
      }
    
    
      /**
       * Returns the width of the padding(s) for the specified side(s).
       * 
       * @param sides the sides from which to calculate the padding. Passing more than one side will yield the sum of the
       *          padding of those sides of the element.
       * @return the sum of the widths of the padding
       */
      public final int getPadding(Side... sides) {
        List<String> list = new ArrayList<String>();
        for (Side side : sides) {
          appendSideToList(list, side, "padding");
        }
    
    
        return getStylePropertyTotal(list);
      }
    
    
      /**
       * Returns the widget's current position. The widget must be attached to return page coordinates.
       * 
       * @param local true to return the element's left and top rather than page coordinates
       * @return the position
       */
      public final Point getPosition(boolean local) {
        if (local) {
          return new Point(getLeft(true), getTop(true));
        }
        return getXY();
      }
    
    
      /**
       * Returns the region of the given element. The element must be part of the DOM tree to have a region.
       * 
       * @return a region containing top, left, bottom, right
       */
      public final Region getRegion() {
        Rectangle bounds = getBounds();
        Region r = new Region();
        r.setLeft(bounds.getX());
        r.setTop(bounds.getY());
        r.setRight(r.getLeft() + bounds.getWidth());
        r.setBottom(r.getTop() + bounds.getHeight());
        return r;
      }
    
    
      /**
       * Returns the right X coordinate of the element (element X position + element width).
       * 
       * @param local <code>true</code> to get the local css position instead of page coordinate
       * @return the right value
       */
      public final int getRight(boolean local) {
        return getOffsetWidth() + (local ? getLeft(true) : getX());
      }
    
    
      /**
       * Returns the body elements current scroll position.
       * 
       * @return the scroll position
       */
      public final Scroll getScroll() {
        if (this.cast() == Document.get().getBody() || this == Document.get().getDocumentElement()) {
          return new Scroll(XDOM.getBodyScrollLeft(), XDOM.getBodyScrollTop());
        } else {
          return new Scroll(getScrollLeft(), getScrollTop());
        }
      }
    
    
      /**
       * Returns the size of the element.
       * 
       * @return the size
       */
      public final Size getSize() {
        return getSize(false);
      }
    
    
      /**
       * Returns the element's size.
       * 
       * @param content true to get the size minus borders and padding
       * @return the size
       */
      public final Size getSize(boolean content) {
        int w = getOffsetWidth();
        int h = getOffsetHeight();
        if (content) {
          Size frameWidth = getFrameSize();
          w -= frameWidth.getWidth();
          h -= frameWidth.getHeight();
        }
        return new Size(Math.max(0, w), Math.max(0, h));
      }
    
    
      /**
       * Returns the element's size (excluding padding and borders), using style attribute before offsets.
       * 
       * @return the size
       */
      public final Size getStyleSize() {
        return getStyleSize(true);
      }
    
    
      /**
       * Returns the element's size, using style attribute before offsets.
       * 
       * @param contentOnly true to exclude padding and borders
       * @return the size
       */
      public final Size getStyleSize(boolean contentOnly) {
        int h = Util.parseInt(getStyle().getProperty("height"), Style.DEFAULT);
        int w = Util.parseInt(getStyle().getProperty("width"), Style.DEFAULT);
    
    
        boolean isBorderBox = isBorderBox();
    
    
        if (isBorderBox && contentOnly && w != Style.DEFAULT) {
          w -= getFrameWidth(Side.LEFT, Side.RIGHT);
          if (w < 0) {
            w = Style.DEFAULT;
          }
        } else if (!isBorderBox && !contentOnly && w != Style.DEFAULT) {
          w += getFrameWidth(Side.LEFT, Side.RIGHT);
        }
        if (isBorderBox && contentOnly && h != Style.DEFAULT) {
          h -= getFrameWidth(Side.TOP, Side.BOTTOM);
          if (h < 0) {
            h = Style.DEFAULT;
          }
        } else if (!isBorderBox && !contentOnly && h != Style.DEFAULT) {
          h += getFrameWidth(Side.TOP, Side.BOTTOM);
        }
    
    
        int offsetWidth = Style.DEFAULT;
        int offsetHeight = Style.DEFAULT;
        if (w == Style.DEFAULT && h == Style.DEFAULT) {
          Size s = getSize(contentOnly);
          offsetWidth = s.getWidth();
          offsetHeight = s.getHeight();
          if (s.getWidth() > 0) {
            w = s.getWidth();
          }
          if (s.getHeight() > 0) {
            h = s.getHeight();
          }
        } else if (w == Style.DEFAULT) {
          offsetWidth = getWidth(contentOnly);
          if (offsetWidth > 0) {
            w = offsetWidth;
          }
        } else if (h == Style.DEFAULT) {
          offsetHeight = getHeight(contentOnly);
          if (offsetHeight > 0) {
            h = offsetHeight;
          }
        }
    
    
        List<String> l = new ArrayList<String>();
        if (w == Style.DEFAULT) {
          l.add("width");
        }
        if (h == Style.DEFAULT) {
          l.add("height");
        }
        Map<String, String> map = getComputedStyle(l);
        if (map != null) {
          String wid = map.get("width");
          if (wid != null) {
            w = Util.parseInt(wid, Style.DEFAULT);
            if (offsetWidth == 0 && isBorderBox && contentOnly && w != Style.DEFAULT && !GXT.isIE()) {
              w -= getFrameWidth(Side.LEFT, Side.RIGHT);
            } else if (GXT.isIE() && isBorderBox && w != Style.DEFAULT && contentOnly) {
              w -= getFrameWidth(Side.LEFT, Side.RIGHT);
            } else if (offsetWidth == 0 && !isBorderBox && !contentOnly && w != Style.DEFAULT) {
              w += getFrameWidth(Side.LEFT, Side.RIGHT);
            }
          }
          String hei = map.get("height");
          if (hei != null) {
            h = Util.parseInt(hei, Style.DEFAULT);
            if (offsetHeight == 0 && isBorderBox && contentOnly && h != Style.DEFAULT && !GXT.isIE()) {
              h -= getFrameWidth(Side.TOP, Side.BOTTOM);
            } else if (GXT.isIE() && isBorderBox && h != Style.DEFAULT && contentOnly) {
              h -= getFrameWidth(Side.TOP, Side.BOTTOM);
            } else if (offsetHeight == 0 && !isBorderBox && !contentOnly && h != Style.DEFAULT) {
              h += getFrameWidth(Side.TOP, Side.BOTTOM);
            }
          }
        }
        if (w == Style.DEFAULT && h == Style.DEFAULT) {
          return new Size(offsetWidth, offsetHeight);
        }
        return new Size(w != Style.DEFAULT ? w : offsetWidth, h != Style.DEFAULT ? h : offsetHeight);
      }
    
    
      /**
       * Returns the element's sub child.
       * 
       * @param depth the child node depth
       * @return the child element
       */
      public final Element getSubChild(int depth) {
        Element child = this;
        while (depth-- > 0) {
          child = child.getChild(0).cast();
        }
        return child;
      }
    
    
      /**
       * Returns the measured width of the element's text.
       * 
       * @return the width
       */
      public final int getTextWidth() {
        String text = getInnerText();
        TextMetrics metrics = TextMetrics.get();
        metrics.bind(this);
        return metrics.getWidth(text);
      }
    
    
      /**
       * Returns the top Y coordinate.
       * 
       * @return the top value
       */
      public final int getTop() {
        return getTop(true);
      }
    
    
      /**
       * Gets the top Y coordinate.
       * 
       * @param local true to get the local css position instead of page coordinate
       * @return the top value
       */
      public final int getTop(boolean local) {
        return local ? Util.parseInt(getStyle().getTop(), 0) : getY();
      }
    
    
      /**
       * Returns the vis mode.
       * 
       * @return the vis mode
       */
      public final native VisMode getVisMode() /*-{
        return this.visMode;
      }-*/;
    
    
      /**
       * Returns the element's width.
       * 
       * @param content true to get the width minus borders and padding
       * @return the width
       */
      public final int getWidth(boolean content) {
        int w = getOffsetWidth();
        if (content) {
          w -= getFrameWidth(Side.LEFT, Side.RIGHT);
        }
        return Math.max(0, w);
      }
    
    
      /**
       * Gets the current X position of the element based on page coordinates. Element must be part of the DOM tree to have
       * page coordinates.
       * 
       * @return the x position of the element
       */
      public final int getX() {
        int x = getAbsoluteLeft();
        return x > 0 ? x - FieldHolder.adjustXYOffset : x;
      }
    
    
      /**
       * Gets the current position of the element based on page coordinates. Element must be part of the DOM tree to have
       * page coordinates.
       * 
       * @return the location
       */
      public final Point getXY() {
        return new Point(getX(), getY());
      }
    
    
      /**
       * Gets the current Y position of the element based on page coordinates.
       * 
       * @return the y position of the element
       */
      public final int getY() {
        int y = getAbsoluteTop();
        return y > 0 ? y - FieldHolder.adjustXYOffset : y;
      }
    
    
      /**
       * Returns the element's z-index.
       * 
       * @return the z-index
       */
      public final int getZIndex() {
        try {
          return Util.parseInt(getStyle().getZIndex(), 0);
        } catch (Exception e) {
          return 0;
        }
      }
    
    
      /**
       * Hides this element.
       */
      public final void hide() {
        setVisible(false);
      }
    
    
      /**
       * Returns the index of the child.
       * 
       * @param child the child
       * @return the index or -1 of not a child
       */
      public final int indexOf(Element child) {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
          if (getChild(i) == child) {
            return i;
          }
        }
        return -1;
      }
    
    
      /**
       * Inserts this element before the passed element.
       * 
       * @param element the element to insert before
       */
      public final void insertBefore(Element element) {
        element.getParentElement().insertBefore(this, element);
      }
    
    
      /**
       * Inserts the elements before this element.
       * 
       * @param elements the elements to insert
       */
      public final void insertBefore(NodeList<Element> elements) {
        Element parent = getParentElement();
        assert parent != null : "cannot insertBefore with null parent";
        for (int i = 0, len = elements.getLength(); i < len; i++) {
          parent.insertBefore(elements.getItem(0), this);
        }
      }
    
    
      /**
       * Inserts an element at the specified index.
       * 
       * @param child the child element
       * @param index the insert location
       */
      public final void insertChild(Element child, int index) {
        DOM.insertChild((com.google.gwt.dom.client.Element) this.cast(), child, index);
      }
    
    
      /**
       * Creates and inserts a child element.
       * 
       * @param html the HTML fragment
       * @return the new child
       */
      public final XElement insertFirst(SafeHtml html) {
        return XElement.as(DomHelper.insertFirst(this, html));
      }
    
    
      /**
       * Inserts an html fragment into this element
       * 
       * @param where where to insert the html in relation to el - beforeBegin, afterBegin, beforeEnd, afterEnd.
       * @param html the HTML fragment
       * @return the inserted node (or nearest related if more than 1 inserted)
       */
      public final XElement insertHtml(String where, SafeHtml html) {
        return XElement.as(DomHelper.insertHtml(where, this, html));
      }
    
    
      /**
       * Returns true if this element matches the passed simple selector (e.g. div.some-class or span:first-child).
       * 
       * @param selector selector
       * @return true if the element matches the selector, else false
       */
      public final boolean is(String selector) {
        return DomQuery.is(this, selector);
      }
    
    
      /**
       * Returns true if the element is a border box.
       * 
       * @return true for border box
       */
      public final boolean isBorderBox() {
        // only supported mode is w3c model as we force strict
        return false;
        // return isBorderBox(this);
      }
    
    
      /**
       * Returns true if the element is part of the browser's DOM.
       * 
       * @return the connected state
       */
      public final boolean isConnected() {
        return Document.get().getBody().isOrHasChild(this);
      }
    
    
      /**
       * <p>Determine whether an element is equal to, or the child of, this element.</p>
       * <p>This implementation delegates to <code>Node.isOrHasChildImpl(Node)</code>, but catches a scenario
       * in IE9 &amp; IE10 where not all elements support the contains() method used by the actual implementation.</p>
       *
       * @param child the potential child element
       * @return <code>true</code> if the relationship holds
       * @see com.google.gwt.dom.client.Node#isOrHasChild(Node)
       */
      public final boolean isOrHasChild(XElement child) {
        try {
          // instead of calling super, casting is necessary for classic dev mode
          Node node = cast();
          return node.isOrHasChild(child);
        } catch (JavaScriptException e) {
          // swallow the exception if it is a manifestation of the IE9 & IE10 bug
          if ((GXT.isIE9() || GXT.isIE10())
              && e.getName().equals("TypeError")
              && e.getMessage().contains("'contains'")) {
            return false;
          } else {
            throw e;
          }
        }
      }
    
    
      /**
       * Returns whether the element is scrollable (x or y).
       * 
       * @return true if scrollable
       */
      public final boolean isScrollable() {
        return isScrollableX() || isScrollableY();
      }
    
    
      /**
       * Returns whether the element is scrollable on the x-axis.
       * 
       * @return true if scrollable on the x-axis
       */
      public final boolean isScrollableX() {
        return getScrollWidth() > getClientWidth();
      }
    
    
      /**
       * Returns whether the element is scrollable on the y-axis.
       * 
       * @return true if scrollable on the y-axis
       */
      public final boolean isScrollableY() {
        return getScrollHeight() > getClientHeight();
      }
    
    
      /**
       * Tests the style for the given value.
       * 
       * @param attr the style name
       * @param value the test value
       * @return true if equal
       */
      public final boolean isStyleAttribute(String attr, String value) {
        String a = getComputedStyle(attr);
        return a != null && a.equals(value);
      }
    
    
      /**
       * Tests style property values for matches.
       * 
       * @param map the map of style property names and values
       * @param matchAll true to match all properties
       * @return true if a match is found, otherwise false
       */
      public final boolean isStyleProperty(Map<String, String> map, boolean matchAll) {
        Set<String> collection = map.keySet();
        FastMap<String> a = getComputedStyle(new ArrayList<String>(collection));
        for (String s : collection) {
          if (map.get(s).equals(a.get(s))) {
            if (!matchAll) {
              return true;
            }
          } else {
            if (matchAll) {
              return false;
            }
          }
        }
        return false;
      }
    
    
      /**
       * Returns whether the element is currently visible.
       * 
       * @return true if visible
       */
      public final boolean isVisible() {
        return isVisible(false);
      }
    
    
      /**
       * Returns whether the element is currently visible.
       * 
       * @param deep true to deep test
       * 
       * @return true if visible
       */
      public final boolean isVisible(boolean deep) {
        Map<String, String> map = new FastMap<String>();
        map.put("visibility", "hidden");
        map.put("display", "none");
        boolean vis = !isStyleProperty(map, false);
        XElement parent = (XElement) getParentElement();
        XElement p = parent != null ? parent : null;
        if (p == null) {
          return false;
        }
        if (!deep || !vis) {
          return vis;
        }
    
    
        while (p != null && p != Document.get().getDocumentElement()) {
          if (!p.isVisible()) {
            return false;
          }
          p = (XElement) p.getParentElement();
        }
        return true;
      }
    
    
      /**
       * <p>Retrieves the data using the request builder and updates the element's contents.</p>
       * <p>Please note that the <code>Response</code> from the <code>RequestBuilder</code> is treated as raw html
       * without any sanitizing. If is up to the caller to ensure that the call does not return unsafe html.</p>
       * <p>This method is subject to change.</p>
       * 
       * @param builder the request builder
       * @return the request that was sent
       */
      public final Request load(RequestBuilder builder) {
        try {
          builder.setCallback(new RequestCallback() {
    
    
            public void onError(Request request, Throwable exception) {
              setInnerSafeHtml(exception != null && exception.getMessage() != null
                  ? SafeHtmlUtils.fromString(exception.getMessage()) : SafeHtmlUtils.EMPTY_SAFE_HTML);
            }
    
    
            public void onResponseReceived(Request request, Response response) {
              setInnerSafeHtml(response != null && response.getText() != null
                  ? SafeHtmlUtils.fromString(response.getText()) : SafeHtmlUtils.EMPTY_SAFE_HTML);
            }
    
    
          });
          return builder.send();
        } catch (Exception e) {
          setInnerSafeHtml(e != null && e.getMessage() != null
              ? SafeHtmlUtils.fromString(e.getMessage()) : SafeHtmlUtils.EMPTY_SAFE_HTML);
          return null;
        }
      }
    
    
      /**
       * Makes an element positionable.
       */
      public final void makePositionable() {
        makePositionable(false);
      }
    
    
      /**
       * Makes an element positionable.
       * 
       * @param absolute <code>true</code> to position absolutely
       */
      public final void makePositionable(boolean absolute) {
        if (absolute) {
          getStyle().setPosition(Position.ABSOLUTE);
        } else {
          String p = getComputedStyle("position");
          if (p == null || "".equals(p) || "static".equals(p) && (!"absolute".equals(p))) {
            getStyle().setPosition(Position.RELATIVE);
          }
        }
      }
    
    
      /**
       * Puts a mask over this element to disable user interaction.
       * 
       * @param message a message to display in the mask
       */
      public final void mask(String message) {
        Mask.mask(this, message);
      }
    
    
      /**
       * Removes all the elements children.
       */
      public final void removeChildren() {
        Element child = null;
        while ((child = getFirstChildElement()) != null) {
          removeChild(child);
        }
        String tag = getTagName().toLowerCase();
        if (!tag.equals("table") && !tag.equals("tbody") && !tag.equals("tr") && !tag.equals("td")) {
          setInnerSafeHtml(SafeHtmlUtils.EMPTY_SAFE_HTML);
        }
      }
    
    
      /**
       * Removes the style names(s) from the element.
       * 
       * @param classNames the style names
       */
      public final void removeClassName(String... classNames) {
        for (int i = 0; i < classNames.length; i++) {
          removeClassName(classNames[i]);
        }
      }
    
    
      /**
       * Removes the style names(s) from the element.
       * 
       * @param className1 the first class name to remove
       * @param className2 the second class name to remove
       */
      public final void removeClassName(String className1, String className2) {
        removeClassName(className1);
        removeClassName(className2);
      }
    
    
      /**
       * Forces the Browser to repaint this element.
       */
      public final void repaint() {
        addClassName(CommonStyles.get().repaint());
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
    
    
          @Override
          public void execute() {
            removeClassName(CommonStyles.get().repaint());
          }
        });
      }
    
    
      /**
       * Replace one class name with another.
       * 
       * @param oldClassName the class name to be replaced
       * @param newClassName the class name to replace it
       * @param deep true to class names on child elements
       */
      public final void replaceClassName(String oldClassName, String newClassName, boolean deep) {
        removeClassName(oldClassName);
        addClassName(newClassName);
        NodeList<Element> nodes = select("." + oldClassName);
        for (int i = 0; i < nodes.getLength(); i++) {
          nodes.getItem(i).replaceClassName(oldClassName, newClassName);
        }
      }
    
    
      /**
       * Restores any elements made visible with {@link #ensureVisible()}.
       * 
       * @param list the meta data list
       */
      public final void restoreVisible(List<FastMap<Object>> list) {
        if (list != null) {
          for (FastMap<Object> m : list) {
            Element e = (Element) m.get("element");
    
    
            Boolean offset = (Boolean) m.get("hasxhideoffset");
            if (offset != null) {
              if (!offset.booleanValue()) {
                e.removeClassName(CommonStyles.get().hideOffsets());
              }
            }
    
    
            Boolean display = (Boolean) m.get("hasxhidedisplay");
            if (display != null) {
              if (display.booleanValue()) {
                e.addClassName(CommonStyles.get().hideDisplay());
              }
            }
    
    
            e.getStyle().setProperty("display", (String) m.get("origd"));
          }
        }
      }
    
    
      /**
       * Scrolls the element into view.
       * 
       * @param container the container element
       * @param hscroll <code>false</code> to disable horizontal scrolling.
       */
      public final void scrollIntoView(Element container, boolean hscroll) {
        scrollIntoView(container, hscroll, 0, 0);
      }
    
    
      /**
       * Scrolls the element into view.
       * 
       * @param container the container element
       * @param hscroll <code>false</code> to disable horizontal scrolling.
       * @param offsetX X offset
       * @param offsetY Y offset
       */
      public final void scrollIntoView(Element container, boolean hscroll, int offsetX, int offsetY) {
        Element c = container != null ? container : Document.get().getBody();
    
    
        Point o = getOffsetsTo(c);
        int l = o.getX();
        int t = o.getY();
        l = l + c.getScrollLeft();
        t = t + c.getScrollTop();
        int b = t + getOffsetHeight() + offsetY;
        int r = l + getOffsetWidth() + offsetX;
    
    
        int ch = c.getClientHeight();
        int ct = c.getScrollTop();
        int cb = ct + ch;
    
    
        if (getOffsetHeight() > ch || t < ct) {
          c.setScrollTop(t);
        } else if (b > cb) {
          c.setScrollTop(b - ch);
        }
    
    
        if (hscroll) {
          int cl = c.getScrollLeft();
          int cw = c.getClientWidth();
          int cr = cl + cw;
    
    
          if (getOffsetWidth() > cw || l < cl) {
            c.setScrollLeft(l);
          } else if (r > cr) {
            c.setScrollLeft(r - cw);
          }
        }
      }
    
    
      /**
       * Scrolls this element the specified scroll point.
       * 
       * @param side the scroll direction
       * @param value the new scroll value
       */
      public final void scrollTo(ScrollDirection side, int value) {
        if (side == ScrollDirection.LEFT) {
          setScrollLeft(value);
        } else {
          setScrollTop(value);
        }
      }
    
    
      /**
       * Selects child nodes based on the passed CSS selector (the selector should not contain an id).
       * 
       * @param selector the selector/xpath query
       * @return the matching elements
       */
      public final NodeList<Element> select(String selector) {
        return DomQuery.select(selector, this);
      }
    
    
      /**
       * Selects a single element.
       * 
       * @param selector the CSS selector
       * @return the matching element or null if no match
       */
      public final XElement selectNode(String selector) {
        Element el = DomQuery.selectNode(selector, this);
        if (el != null) {
          return XElement.as(el);
        }
        return null;
      }
    
    
      /**
       * Sets the attribute, determined by it names, using the given name space and value.
       * 
       * @param nameSpace the name space of the attribute
       * @param name the attribute name
       * @param value the value of the attribute
       */
      public final native void setAttributeNS(String nameSpace, String name, String value)/*-{
        this.setAttributeNS(nameSpace, name, value);
      }-*/;
    
    
      /**
       * Adds or removes a border.
       * 
       * @param show the show state
       */
      public final void setBorders(boolean show) {
        if (show) {
          addClassName(ThemeStyles.get().style().border());
          getStyle().setBorderWidth(1, Unit.PX);
        } else {
          removeClassName(ThemeStyles.get().style().border());
          getStyle().setBorderWidth(0, Unit.PX);
        }
      }
    
    
      /**
       * Sets the element's bounds.
       * 
       * @param x the x coordinate
       * @param y the y coordinate
       * @param width the new width
       * @param height the new height
       */
      public final void setBounds(int x, int y, int width, int height) {
        setBounds(x, y, width, height, false);
      }
    
    
      /**
       * Sets the element's bounds.
       * 
       * @param x the x coordinate
       * @param y the y coordinate
       * @param width the new width
       * @param height the new height
       * @param adjust true to adjust for box model issues
       */
      public final void setBounds(int x, int y, int width, int height, boolean adjust) {
        setXY(x, y);
        setSize(width, height, adjust);
      }
    
    
      /**
       * Sets the element's bounds.
       * 
       * @param bounds the new bounds
       */
      public final void setBounds(Rectangle bounds) {
        setBounds(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
      }
    
    
      /**
       * Sets the element's bounds.
       * 
       * @param bounds the new bounds
       * @param content <code>true</code> to adjust for box model issues
       */
      public final void setBounds(Rectangle bounds, boolean content) {
        setBounds(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(), content);
      }
    
    
      /**
       * Adds or removes the class name.
       * 
       * @param cls the style name
       * @param add true to add, false to remove
       */
      public final void setClassName(String cls, boolean add) {
        if (add) {
          addClassName(cls);
        } else {
          removeClassName(cls);
        }
      }
    
    
      /**
       * Sets the CSS display property.
       * 
       * @param display true to display the element using its default display
       */
      public final void setDisplayed(boolean display) {
        getStyle().setDisplay(display ? Display.BLOCK : Display.NONE);
        if (getLayer() != null) {
          if (display) {
            getLayer().sync(true);
          } else {
            getLayer().hideUnders();
          }
        }
      }
    
    
      /**
       * Sets the elements height.
       * 
       * @param height the height
       */
      public final void setHeight(int height) {
        setHeight(height, false);
      }
    
    
      /**
       * Sets the elements height.
       * 
       * @param height the height
       * @param adjust <code>true</code> to adjust for box model issues
       */
      public final void setHeight(int height, boolean adjust) {
        if (adjust && !isBorderBox()) {
          height -= getFrameWidth(Side.TOP, Side.BOTTOM);
        }
        if (height >= 0) {
          getStyle().setPropertyPx("height", height);
        }
      }
    
    
      /**
       * Sets the elements height.
       * 
       * @param height the height
       */
      public final void setHeight(String height) {
        getStyle().setProperty("height", addUnits(height, "px"));
      }
    
    
      /**
       * Sets the element's left position directly using CSS style (instead of {@link #setX}).
       * 
       * @param left the left value in pixels
       */
      public final void setLeft(int left) {
        getStyle().setLeft(left, Unit.PX);
        if (getLayer() != null) {
          getLayer().sync(false);
        }
      }
    
    
      /**
       * Quick set left and top adding default units.
       * 
       * @param left the left value
       * @param top the top value
       */
      public final void setLeftTop(int left, int top) {
        setLeft(left);
        setTop(top);
      }
    
    
      /**
       * Sets the elements's margin.
       * 
       * @param margin the margin
       */
      public final void setMargins(int margin) {
        setMargins(new Margins(margin));
      }
    
    
      /**
       * Sets the elements's margin.
       * 
       * @param margin the margin
       */
      public final void setMargins(Margins margin) {
        if (margin != null) {
          getStyle().setMarginLeft(margin.getLeft(), Unit.PX);
          getStyle().setMarginTop(margin.getTop(), Unit.PX);
          getStyle().setMarginRight(margin.getRight(), Unit.PX);
          getStyle().setMarginBottom(margin.getBottom(), Unit.PX);
        }
      }
    
    
      /**
       * Cross-browser support for setting opacity.
       * 
       * @param opacity the opacity
       */
      public final void setOpacity(double opacity) {
        FieldHolder.computedStyle.setStyleAttribute(this, "opacity", opacity);
      }
    
    
      /**
       * Sets the elements's padding.
       * 
       * @param padding the padding
       */
      public final void setPadding(Padding padding) {
        if (padding != null) {
          getStyle().setPaddingLeft(padding.getLeft(), Unit.PX);
          getStyle().setPaddingTop(padding.getTop(), Unit.PX);
          getStyle().setPaddingRight(padding.getRight(), Unit.PX);
          getStyle().setPaddingBottom(padding.getBottom(), Unit.PX);
        }
      }
    
    
      /**
       * Sets the element's size.
       * 
       * @param width the new width
       * @param height the new height
       */
      public final void setSize(int width, int height) {
        setSize(width, height, false);
      }
    
    
      /**
       * Set the size of the element.
       * 
       * @param width the new width
       * @param height the new height
       * @param adjust <code>true</code> to adjust for box model issues
       */
      public final void setSize(int width, int height, boolean adjust) {
        if (adjust && !isBorderBox()) {
          Size frameWidth = getFrameSize();
          width -= frameWidth.getWidth();
          height -= frameWidth.getHeight();
        }
        if (width >= 0) {
          getStyle().setPropertyPx("width", width);
        }
        if (height >= 0) {
          getStyle().setPropertyPx("height", height);
        }
        if (getLayer() != null) {
          getLayer().sync(false);
        }
      }
    
    
      /**
       * Sets the element's size.
       * 
       * @param size the size
       */
      public final void setSize(Size size) {
        setSize(size.getWidth(), size.getHeight());
      }
    
    
      /**
       * Sets the element's top position directly using CSS style (instead of {@link #setY}).
       * 
       * @param top the top value in pixels
       */
      public final void setTop(int top) {
        getStyle().setTop(top, Unit.PX);
        if (getLayer() != null) {
          getLayer().sync(false);
        }
      }
    
    
      /**
       * Sets the elements CSS visibility property.
       * 
       * @param visible true for visible
       */
      public final void setVisibility(boolean visible) {
        getStyle().setVisibility(visible ? Visibility.VISIBLE : Visibility.HIDDEN);
      }
    
    
      /**
       * Sets the visibility of the element using the {@link #getVisMode()}.
       * 
       * @param visible whether the element is visible
       */
      public final void setVisible(boolean visible) {
        if (getVisMode() == null || getVisMode() == VisMode.DISPLAY) {
          setDisplayed(visible);
        } else {
          setVisibility(visible);
        }
      }
    
    
      /**
       * Sets the vis mode (defaults to {@link VisMode#DISPLAY}.
       * 
       * @param visMode the vis mode
       */
      public final native void setVisMode(VisMode visMode) /*-{
        this.visMode = visMode;
      }-*/;
    
    
      /**
       * Sets the element's width.
       * 
       * @param width the new width
       */
      public final void setWidth(int width) {
        setWidth(width, false);
      }
    
    
      /**
       * Sets the elements's width.
       * 
       * @param width the new width
       * @param adjust <code>true</code> to adjust for box model issues
       */
      public final void setWidth(int width, boolean adjust) {
        if (adjust && !isBorderBox()) {
          width -= getFrameWidth(Side.LEFT, Side.RIGHT);
        }
        if (width >= 0) {
          getStyle().setPropertyPx("width", width);
        }
      }
    
    
      /**
       * Sets the elements width.
       * 
       * @param width the width
       */
      public final void setWidth(String width) {
        getStyle().setProperty("width", addUnits(width, "px"));
      }
    
    
      /**
       * Sets the X position of the element based on page coordinates. Element must be part of the DOM tree to have page
       * coordinates.
       * 
       * @param x the x coordinate
       */
      public final void setX(int x) {
        setXY(x, Style.DEFAULT);
      }
    
    
      /**
       * Sets the elements position in page coordinates.
       * 
       * @param x the x coordinate
       * @param y the y coordinate
       */
      public final void setXY(int x, int y) {
        setXY(new Point(x, y));
      }
    
    
      /**
       * Sets the element's position in page coordinates.
       * 
       * @param p the position
       */
      public final void setXY(Point p) {
        makePositionable();
        Point pts = translatePoints(p);
        if (p.getX() != Style.DEFAULT) {
          setLeft(pts.getX());
        }
        if (p.getY() != Style.DEFAULT) {
          setTop(pts.getY());
        }
      }
    
    
      /**
       * Sets the Y position of the element based on page coordinates. Element must be part of the DOM tree to have page
       * coordinates.
       * 
       * @param y the y coordinate
       */
      public final void setY(int y) {
        setXY(Style.DEFAULT, y);
      }
    
    
      /**
       * Sets the element's z-index.
       * 
       * @param zIndex the z-index value
       */
      public final void setZIndex(int zIndex) {
        DOM.setIntStyleAttribute(this, "zIndex", Math.max(0, zIndex));
      }
    
    
      /**
       * Shows this element.
       */
      public final void show() {
        setVisible(true);
      }
    
    
      /**
       * Replace one class name with another.
       * 
       * @param oldClassName the class name to be replaced, empty strings allowed
       * @param newClassName the class name to replace it, empty strings allowed
       */
      public final void swapClassName(String oldClassName, String newClassName) {
        if (!oldClassName.equals("")) {
          removeClassName(oldClassName);
        }
        if (!newClassName.equals("")) {
          addClassName(newClassName);
        }
      }
    
    
      /**
       * Translates the passed page coordinates into left/top css values for this element.
       * 
       * @param p the coordinates
       * @return the translated coordinates
       */
      public final Point translatePoints(Point p) {
        List<String> list = new ArrayList<String>(3);
        list.add("position");
        list.add("left");
        list.add("top");
    
    
        Map<String, String> map = getComputedStyle(list);
        boolean relative = "relative".equals(map.get("position"));
        int l = Util.parseInt(map.get("left"), -11234);
        int t = Util.parseInt(map.get("top"), -11234);
    
    
        l = l != -11234 ? l : (relative ? 0 : getOffsetLeft());
        t = t != -11234 ? t : (relative ? 0 : getOffsetTop());
    
    
        Point o = getXY();
        return new Point(p.getX() - o.getX() + l, p.getY() - o.getY() + t);
      }
    
    
      /**
       * Removes a previously applied mask.
       */
      public final void unmask() {
        Mask.unmask(this);
      }
    
    
      /**
       * Unwraps the child element.
       *
       * @param child the child to be unwrapped
       * @param bounds the original bounds
       */
      public final void unwrap(XElement child, Rectangle bounds) {
        child.setLeftTop(bounds.getX(), bounds.getY());
        XElement p = getParentElement().cast();
        int pos = p.getChildIndex(this);
        p.insertChild(child, pos);
        p.removeChild(this);
      }
    
    
      /**
       * Sets the element's z-index using {@link XDOM#getTopZIndex()} to ensure it has the highest values.
       * 
       * @param adj the adjustment to be applied to the z-index value
       */
      public final void updateZIndex(int adj) {
        getStyle().setZIndex(XDOM.getTopZIndex() + adj);
      }
    
    
      /**
       * Wraps the element with the specified wrapper. The wrapper will have the same size and position of the element. The
       * original bounds can be used to 'unwrap' the element.
       * 
       * @param wrapper the wrapper element
       * @return the original bounds
       */
      public final Rectangle wrap(Element wrapper) {
        XElement wrap = XElement.as(wrapper);
        wrap.setVisible(false);
    
    
        String pos = getStyle().getPosition();
        wrap.getStyle().setProperty("position", pos);
    
    
        int l = getLeft();
        int t = getTop();
    
    
        setLeft(5000);
        setVisible(true);
    
    
        int h = getComputedHeight();
        int w = getComputedWidth();
    
    
        setLeft(1);
        getStyle().setOverflow(Overflow.HIDDEN);
        setVisible(false);
    
    
        wrap.insertBefore(this);
        wrap.appendChild(this);
    
    
        wrap.getStyle().setOverflow(Overflow.HIDDEN);
    
    
        wrap.setLeft(l);
        wrap.setTop(t);
    
    
        setTop(0);
        setLeft(0);
    
    
        return new Rectangle(l, t, w, h);
      }
    
    
      protected final Point getConstrainToXY(Element elem, Point proposedXY) {
        int vw, vh, vx = 0, vy = 0;
        if (elem == Document.get().getBody()) {
          vw = XDOM.getViewportSize().getWidth();
          vh = XDOM.getViewportSize().getHeight();
        } else {
          vw = elem.getOffsetWidth();
          vh = elem.getOffsetHeight();
          vx = elem.getAbsoluteLeft();
          vy = elem.getAbsoluteTop();
        }
    
    
        Point xy = proposedXY;
        int x = xy.getX();
        int y = xy.getY();
    
    
        int vr = vx + vw;
        int vb = vy + vh;
    
    
        int w = getOffsetWidth();
        int h = getOffsetHeight();
    
    
        if ((x + w) > vr) {
          x = vr - w;
        }
        if ((y + h) > vb) {
          y = vb - h;
    
    
        }
    
    
        // then make sure top/left isn't negative
        if (x < vx) {
          x = vx;
        }
        if (y < vy) {
          y = vy;
        }
    
    
        return new Point(x, y);
      }
    
    
      final native Layer getLayer() /*-{
        return this.layer;
      }-*/;
    
    
      final native void setLayer(Layer layer) /*-{
        this.layer = layer;
      }-*/;
    
    
      private void appendSideToList(List<String> list, Side side, String prop) {
        String s = side.toString();
        if (prop != null) {
          String temp = prop + s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
          if (prop.equals("border")) {
            temp += "Width";
          }
          list.add(temp);
        }
      }
    
    
      private int getStylePropertyTotal(List<String> props) {
        int total = 0;
        FastMap<String> map = getComputedStyle(props);
        for (String s : map.keySet()) {
          total += Util.parseInt(map.get(s), 0);
        }
        return total;
      }
    
    
      private final boolean isLeftOrRight(String s) {
        return FieldHolder.leftOrRight.test(s);
      }
    
    
    }

Similar Threads

  1. Replies: 0
    Last Post: 25 Sep 2015, 11:16 AM
  2. Mask.mask(XElement, String) issue
    By audra in forum Sencha GXT Bugs
    Replies: 1
    Last Post: 10 Apr 2012, 6:47 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •