1285 HTMLElement* WebViewCore::retrieveElement(int x, int y,
1286 const QualifiedName& tagName)
1287 {
1288 HitTestResult hitTestResult = m_mainFrame->eventHandler()
1289 ->hitTestResultAtPoint(IntPoint(x, y), false, false,
1290 DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly,
1291 IntSize(1, 1));
1292 if (!hitTestResult.innerNode() || !hitTestResult.innerNode()->inDocument()) {
1293 ALOGE("Should not happen: no in document Node found");
1294 return 0;
1295 }
1296 const ListHashSet<RefPtr<Node> >& list = hitTestResult.rectBasedTestResult();
1297 if (list.isEmpty()) {
1298 ALOGE("Should not happen: no rect-based-test nodes found");
1299 return 0;
1300 }
1301 Node* node = hitTestResult.innerNode();
1302 Node* element = node;
1303 while (element && (!element->isElementNode()
1304 || !element->hasTagName(tagName))) {
1305 element = element->parentNode();
1306 }
1307 return static_cast<WebCore::HTMLElement*>(element);
1308 }
1836
1837 AndroidHitTestResult WebViewCore::hitTestAtPoint(int x, int y, int slop, bool doMoveMouse)
1838 {
1839 if (doMoveMouse)
1840 moveMouse(x, y, 0, true);
1841 HitTestResult hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(IntPoint(x, y),
1842 false, false, DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly, IntSize(slop, slop));
1843 AndroidHitTestResult androidHitResult(this, hitTestResult);
1844 if (!hitTestResult.innerNode() || !hitTestResult.innerNode()->inDocument()) {
1845 ALOGE("Should not happen: no in document Node found");
1846 return androidHitResult;
1847 }
1848 const ListHashSet<RefPtr<Node> >& list = hitTestResult.rectBasedTestResult();
1849 if (list.isEmpty()) {
1850 ALOGE("Should not happen: no rect-based-test nodes found");
1851 return androidHitResult;
1852 }
1853 Frame* frame = hitTestResult.innerNode()->document()->frame();
1854 Vector<TouchNodeData> nodeDataList;
1855 if (hitTestResult.innerNode() != hitTestResult.innerNonSharedNode()
1856 && hitTestResult.innerNode()->hasTagName(WebCore::HTMLNames::areaTag)) {
1857 HTMLAreaElement* area = static_cast<HTMLAreaElement*>(hitTestResult.innerNode());
1858 androidHitResult.hitTestResult().setURLElement(area);
1859 androidHitResult.highlightRects().append(area->computeRect(
1860 hitTestResult.innerNonSharedNode()->renderer()));
1861 return androidHitResult;
1862 }
1863 ListHashSet<RefPtr<Node> >::const_iterator last = list.end();
1864 for (ListHashSet<RefPtr<Node> >::const_iterator it = list.begin(); it != last; ++it) {
1865 TODO
1866
1867 if (it->get()->document()->frame() != frame)
1868 continue;
1869
1870 bool found = false;
1871 Node* eventNode = it->get();
1872 Node* innerNode = eventNode;
1873 while (eventNode) {
1874 RenderObject* render = eventNode->renderer();
1875 if (render && (render->isBody() || render->isRenderView()))
1876 break;
1877 if (nodeIsClickableOrFocusable(eventNode)) {
1878 found = true;
1879 break;
1880 }
1881
1882
1883 TODO
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898 if (render && !render->style()->hasAutoZIndex())
1899 break;
1900 eventNode = eventNode->parentNode();
1901 }
1902
1903 if (!found)
1904 continue;
1905
1906 Vector<TouchNodeData>::const_iterator nlast = nodeDataList.end();
1907 for (Vector<TouchNodeData>::const_iterator n = nodeDataList.begin(); n != nlast; ++n) {
1908
1909 if (eventNode == n->mUrlNode) {
1910 found = false;
1911 break;
1912 }
1913 }
1914 if (!found)
1915 continue;
1916
1917 found = false;
1918 IntRect rect = getAbsoluteBoundingBox(eventNode);
1919 if (rect.isEmpty()) {
1920
1921 if (!eventNode->isContainerNode())
1922 continue;
1923
1924
1925 Node* child = static_cast<const ContainerNode*>(eventNode)->firstChild();
1926 while (child) {
1927 IntRect childrect;
1928 if (child->renderer())
1929 childrect = getAbsoluteBoundingBox(child);
1930 if (!childrect.isEmpty()) {
1931 rect.unite(childrect);
1932 child = child->traverseNextSibling(eventNode);
1933 } else
1934 child = child->traverseNextNode(eventNode);
1935 }
1936 }
1937 for (int i = nodeDataList.size() - 1; i >= 0; i--) {
1938 TouchNodeData n = nodeDataList.at(i);
1939
1940 if (rect.contains(n.mBounds)) {
1941 found = true;
1942 break;
1943 }
1944
1945 if (n.mBounds.contains(rect))
1946 nodeDataList.remove(i);
1947 }
1948 if (!found) {
1949 TouchNodeData newNode;
1950 newNode.mUrlNode = eventNode;
1951 newNode.mBounds = rect;
1952 newNode.mInnerNode = innerNode;
1953 nodeDataList.append(newNode);
1954 }
1955 }
1956 if (!nodeDataList.size()) {
1957 androidHitResult.searchContentDetectors();
1958 return androidHitResult;
1959 }
1960
1961 TouchNodeData final;
1962 final.mUrlNode = 0;
1963 IntPoint docPos = frame->view()->windowToContents(m_mousePos);
1964 IntRect testRect(docPos.x() - slop, docPos.y() - slop, 2 * slop + 1, 2 * slop + 1);
1965 int area = 0;
1966 Vector<TouchNodeData>::const_iterator nlast = nodeDataList.end();
1967 for (Vector<TouchNodeData>::const_iterator n = nodeDataList.begin(); n != nlast; ++n) {
1968 IntRect rect = n->mBounds;
1969 rect.intersect(testRect);
1970 int a = rect.width() * rect.height();
1971 if (a > area || !final.mUrlNode) {
1972 final = *n;
1973 area = a;
1974 }
1975 }
1976
1977 if (final.mUrlNode) {
1978
1979 androidHitResult.hitTestResult().setInnerNode(final.mInnerNode);
1980 androidHitResult.hitTestResult().setInnerNonSharedNode(final.mInnerNode);
1981 if (final.mUrlNode->isElementNode()) {
1982
1983 androidHitResult.setURLElement(static_cast<Element*>(final.mUrlNode));
1984 } else {
1985 androidHitResult.setURLElement(0);
1986 }
1987 Vector<IntRect>& highlightRects = androidHitResult.highlightRects();
1988 if (doMoveMouse && highlightRects.size() > 0) {
1989
1990
1991 IntRect foundIntersection;
1992 IntRect inputRect = IntRect(x - slop, y - slop,
1993 slop * 2 + 1, slop * 2 + 1);
1994 for (size_t i = 0; i < highlightRects.size(); i++) {
1995 IntRect& hr = highlightRects[i];
1996 IntRect test = inputRect;
1997 test.intersect(hr);
1998 if (!test.isEmpty()) {
1999 foundIntersection = test;
2000 break;
2001 }
2002 }
2003 if (!foundIntersection.isEmpty() && !foundIntersection.contains(x, y)) {
2004 IntPoint pt = foundIntersection.center();
2005 moveMouse(pt.x(), pt.y(), 0, true);
2006 }
2007 }
2008 } else {
2009 androidHitResult.searchContentDetectors();
2010 }
2011 return androidHitResult;
2012 }