Fixes Issue #1218 Improves the speed for DOM.isOrHasChild by adding more browser specialization. The techniques used are: IE6/7 - Node.contains with special case for equality. Safari - Tree walk (Node.contains broken on Safari2). Mozilla - Node.compareDocumentPosition Opera - Node.contains Patch by: mmastrac, knorton Review by: jgw, ecc git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1829 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java index 7902753..5dd4ba9 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
@@ -244,12 +244,9 @@ @Override public native boolean isOrHasChild(Element parent, Element child) /*-{ - while (child) { - if (parent.uniqueID == child.uniqueID) - return true; - child = child.parentElement; - } - return false; + // An extra equality check is required due to the fact that + // elem.contains(elem) is false if elem is not attached to the DOM. + return (parent.uniqueID == child.uniqueID) || parent.contains(child); }-*/; @Override
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java b/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java index 055b0f7..72b18c6 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java
@@ -80,25 +80,9 @@ @Override public native boolean isOrHasChild(Element parent, Element child) /*-{ - while (child) { - if (parent.isSameNode(child)) { - return true; - } - - try { - child = child.parentNode; - } catch(e) { - // Give up on 'Permission denied to get property - // HTMLDivElement.parentNode' - // See https://bugzilla.mozilla.org/show_bug.cgi?id=208427 - return false; - } - - if (child && (child.nodeType != 1)) { - child = null; - } - } - return false; + // For more information about compareDocumentPosition, see: + // http://www.quirksmode.org/blog/archives/2006/01/contains_for_mo.html + return parent.isSameNode(child) || !!(parent.compareDocumentPosition(child) & 16); }-*/; @Override
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplSafari.java b/user/src/com/google/gwt/user/client/impl/DOMImplSafari.java index 5bad5b4..155e084 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImplSafari.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImplSafari.java
@@ -120,4 +120,18 @@ select.insertBefore(newOption, select.children[index]); } }-*/; + + @Override + public native boolean isOrHasChild(Element parent, Element child) /*-{ + while (child) { + if (parent == child) { + return true; + } + child = child.parentNode; + if (child && (child.nodeType != 1)) { + child = null; + } + } + return false; + }-*/; }
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java index 14367e7..64f0a73 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
@@ -169,16 +169,7 @@ @Override public native boolean isOrHasChild(Element parent, Element child) /*-{ - while (child) { - if (parent == child) { - return true; - } - child = child.parentNode; - if (child && (child.nodeType != 1)) { - child = null; - } - } - return false; + return parent.contains(child); }-*/; @Override
diff --git a/user/test/com/google/gwt/user/client/ui/DOMTest.java b/user/test/com/google/gwt/user/client/ui/DOMTest.java index b2904cc..195d813 100644 --- a/user/test/com/google/gwt/user/client/ui/DOMTest.java +++ b/user/test/com/google/gwt/user/client/ui/DOMTest.java
@@ -167,10 +167,18 @@ public void testIsOrHasChild() { Element div = DOM.createDiv(); Element childDiv = DOM.createDiv(); + assertFalse(DOM.isOrHasChild(div, childDiv)); + assertTrue(DOM.isOrHasChild(div, div)); + DOM.appendChild(div, childDiv); assertTrue(DOM.isOrHasChild(div, childDiv)); assertFalse(DOM.isOrHasChild(childDiv, div)); + + DOM.appendChild(RootPanel.getBodyElement(), div); + assertTrue(DOM.isOrHasChild(div, childDiv)); + assertTrue(DOM.isOrHasChild(div, div)); + assertFalse(DOM.isOrHasChild(childDiv, div)); } /**