Source/WebCore/ChangeLog

112012-10-02 Allan Sandfeld Jensen <allan.jensen@digia.com>
22
 3 Move side-effects on hover/active state out of hit-testing.
 4 https://bugs.webkit.org/show_bug.cgi?id=98168
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This patch changes hit-testing so that it no longer has any side-effects and is really purely
 9 a hit-test. This will help enable further clean-up and optimizations.
 10
 11 No change in functionality. No new tests.
 12
 13 * dom/Document.cpp:
 14 (WebCore::Document::prepareMouseEvent):
 15 (WebCore::Document::updateHoverActiveState):
 16 * dom/Document.h:
 17 (Document):
 18 * page/EventHandler.cpp:
 19 (WebCore::EventHandler::hitTestResultAtPoint):
 20 (WebCore::EventHandler::sendContextMenuEventForKey):
 21 (WebCore::EventHandler::hoverTimerFired):
 22 * rendering/RenderView.cpp:
 23 (WebCore::RenderView::hitTest):
 24
 252012-10-02 Allan Sandfeld Jensen <allan.jensen@digia.com>
 26
327 Disambiguate resultFramePoint and original hit-test point
428 https://bugs.webkit.org/show_bug.cgi?id=98139
529

Source/WebCore/dom/Document.cpp

@@MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& r
30693069 renderView()->hitTest(request, result);
30703070
30713071 if (!request.readOnly())
3072  updateStyleIfNeeded();
 3072 updateHoverActiveState(request, result.innerNode());
30733073
30743074 return MouseEventWithHitTestResults(event, result);
30753075}

@@static RenderObject* nearestCommonHoverAncestor(RenderObject* obj1, RenderObject
57605760 return 0;
57615761}
57625762
5763 void Document::updateHoverActiveState(const HitTestRequest& request, HitTestResult& result)
 5763void Document::updateHoverActiveState(const HitTestRequest& request, Node* innerNode)
57645764{
5765  // We don't update :hover/:active state when the result is marked as readOnly.
5766  if (request.readOnly())
5767  return;
5768 
5769  Node* innerNodeInDocument = result.innerNode();
5770  ASSERT(!innerNodeInDocument || innerNodeInDocument->document() == this);
 5765 ASSERT(!request.readOnly());
 5766 ASSERT(!innerNode || innerNode->document() == this);
57715767
57725768 Node* oldActiveNode = activeNode();
57735769 if (oldActiveNode && !request.active()) {

@@void Document::updateHoverActiveState(const HitTestRequest& request, HitTestResu
57805776 }
57815777 setActiveNode(0);
57825778 } else {
5783  Node* newActiveNode = innerNodeInDocument;
 5779 Node* newActiveNode = innerNode;
57845780 if (!oldActiveNode && newActiveNode && request.active() && !request.touchMove()) {
57855781 // We are setting the :active chain and freezing it. If future moves happen, they
57865782 // will need to reference this chain.

@@void Document::updateHoverActiveState(const HitTestRequest& request, HitTestResu
58015797 bool mustBeInActiveChain = request.active() && request.move();
58025798
58035799 RefPtr<Node> oldHoverNode = hoverNode();
5804  // Clear the :hover chain when the touch gesture is over.
 5800
58055801 if (request.touchRelease()) {
5806  if (oldHoverNode) {
5807  for (RenderObject* curr = oldHoverNode->renderer(); curr; curr = curr->hoverAncestor()) {
5808  if (curr->node() && !curr->isText())
5809  curr->node()->setHovered(false);
5810  }
5811  setHoverNode(0);
5812  }
5813  // A touch release can not set new hover or active target.
5814  return;
 5802 // A touch release does not set a new hover target.
 5803 innerNode = 0;
58155804 }
58165805
58175806 // Check to see if the hovered node has changed.
58185807 // If it hasn't, we do not need to do anything.
5819  Node* newHoverNode = innerNodeInDocument;
 5808 Node* newHoverNode = innerNode;
58205809 while (newHoverNode && !newHoverNode->renderer())
58215810 newHoverNode = newHoverNode->parentOrHostNode();
58225811

@@void Document::updateHoverActiveState(const HitTestRequest& request, HitTestResu
58575846 nodesToAddToChain[i]->setActive(true);
58585847 nodesToAddToChain[i]->setHovered(true);
58595848 }
 5849
 5850 updateStyleIfNeeded();
58605851}
58615852
58625853void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const

Source/WebCore/dom/Document.h

@@public:
703703 void hoveredNodeDetached(Node*);
704704 void activeChainNodeDetached(Node*);
705705
706  void updateHoverActiveState(const HitTestRequest&, HitTestResult&);
 706 void updateHoverActiveState(const HitTestRequest&, Node* innerNode);
707707
708708 // Updates for :target (CSS3 selector).
709709 void setCSSTarget(Element*);

Source/WebCore/page/EventHandler.cpp

@@HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, bool
10761076 hitType |= HitTestRequest::IgnoreClipping;
10771077 if (allowShadowContent)
10781078 hitType |= HitTestRequest::AllowShadowContent;
1079  m_frame->contentRenderer()->hitTest(HitTestRequest(hitType), result);
 1079 HitTestRequest request(hitType);
 1080 m_frame->contentRenderer()->hitTest(request, result);
 1081 if (!request.readOnly())
 1082 m_frame->document()->updateHoverActiveState(request, result.innerNode());
10801083
10811084 while (true) {
10821085 Node* n = result.innerNode();

@@HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, bool
10941097 result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop());
10951098 HitTestResult widgetHitTestResult(widgetPoint, padding.height(), padding.width(), padding.height(), padding.width());
10961099 widgetHitTestResult.setOriginalFramePoint(result.originalFramePoint());
1097  frame->contentRenderer()->hitTest(HitTestRequest(hitType), widgetHitTestResult);
 1100 frame->contentRenderer()->hitTest(request, widgetHitTestResult);
10981101 result = widgetHitTestResult;
 1102 if (!request.readOnly())
 1103 frame->document()->updateHoverActiveState(request, result.innerNode());
10991104
11001105 if (testScrollbars == ShouldHitTestScrollbars) {
11011106 Scrollbar* eventScrollbar = view->scrollbarAtPoint(roundedIntPoint(point));

@@bool EventHandler::sendContextMenuEventForKey()
27232728 targetNode = doc;
27242729
27252730 // Use the focused node as the target for hover and active.
2726  HitTestResult result(position);
2727  result.setInnerNode(targetNode);
2728  HitTestRequest request(HitTestRequest::Active);
2729  doc->updateHoverActiveState(request, result);
2730  doc->updateStyleIfNeeded();
 2731 doc->updateHoverActiveState(HitTestRequest::Active, targetNode);
27312732
27322733 // The contextmenu event is a mouse event even when invoked using the keyboard.
27332734 // This is required for web compatibility.

@@void EventHandler::hoverTimerFired(Timer<EventHandler>*)
28572858 HitTestRequest request(HitTestRequest::Move);
28582859 HitTestResult result(view->windowToContents(m_currentMousePosition));
28592860 renderer->hitTest(request, result);
2860  m_frame->document()->updateStyleIfNeeded();
 2861 m_frame->document()->updateHoverActiveState(request, result.innerNode());
28612862 }
28622863 }
28632864}

Source/WebCore/rendering/RenderView.cpp

@@bool RenderView::hitTest(const HitTestRequest& request, const HitTestLocation& l
9494{
9595 bool inside = layer()->hitTest(request, location, result);
9696
97  // Next set up the correct :hover/:active state along the new chain.
98  document()->updateHoverActiveState(request, result);
99 
10097 return inside;
10198}
10299