ProximityDetector.cpp [plain text]
#include "config.h"
#include "ProximityDetector.h"
#include "Document.h"
#include "Element.h"
#include "ExceptionCode.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "RenderLayer.h"
#include "RenderObject.h"
#include "RenderView.h"
#include "WebPage_p.h"
using namespace WebCore;
namespace BlackBerry {
namespace WebKit {
static int getPriorityLevel(Node* node)
{
if (node->isTextNode())
return 1;
if (!node->isElementNode())
return 0;
Element* element = toElement(node);
ASSERT(element);
ExceptionCode ec = 0;
if (element->webkitMatchesSelector("img,obj", ec))
return 1;
if (element->hasTagName(HTMLNames::pTag))
return 2;
if (element->webkitMatchesSelector("h1,h2,h3,h4,h5,h6", ec))
return 3;
return 0;
}
ProximityDetector::ProximityDetector(WebPagePrivate* webPage)
: m_webPage(webPage)
{
}
ProximityDetector::~ProximityDetector()
{
}
IntPoint ProximityDetector::findBestPoint(const IntPoint& documentPos, const IntRect& documentPaddingRect)
{
ASSERT(m_webPage);
if (!m_webPage->m_mainFrame)
return documentPos;
Document* document = m_webPage->m_mainFrame->document();
if (!document || !document->frame()->view())
return documentPos;
unsigned left = -documentPaddingRect.x();
unsigned top = -documentPaddingRect.y();
unsigned right = documentPaddingRect.maxX();
unsigned bottom = documentPaddingRect.maxY();
IntPoint frameContentPos(document->frame()->view()->windowToContents(m_webPage->m_mainFrame->view()->contentsToWindow(documentPos)));
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
HitTestResult result(frameContentPos, top, right, bottom, left);
document->renderView()->layer()->hitTest(request, result);
IntPoint bestPoint = documentPos;
int bestPriority = 0;
ListHashSet<RefPtr<Node> > intersectedNodes = result.rectBasedTestResult();
ListHashSet<RefPtr<Node> >::const_iterator it = intersectedNodes.begin();
ListHashSet<RefPtr<Node> >::const_iterator end = intersectedNodes.end();
for ( ; it != end; ++it) {
Node* curNode = (*it).get();
if (!curNode || !curNode->renderer())
continue;
IntRect curRect = curNode->renderer()->absoluteBoundingBoxRect(true );
IntRect hitTestRect = HitTestLocation::rectForPoint(documentPos, top, right, bottom, left);
if (!hitTestRect.contains(curRect.location()))
continue;
int priority = getPriorityLevel(curNode);
if (!priority)
continue;
bool equalPriorityAndCloser = (priority == bestPriority) && (documentPos.distanceSquaredToPoint(bestPoint) > documentPos.distanceSquaredToPoint(curRect.location()));
if (priority > bestPriority || equalPriorityAndCloser) {
bestPoint = curRect.location(); bestPriority = priority;
}
}
return bestPoint;
}
}
}