WebCore/rendering/render_layer.cpp

@@void RenderLayer::clearClipRect()
13351335 }
13361336}
13371337
1338 static RenderObject* commonAncestor(RenderObject* obj1, RenderObject* obj2)
1339 {
1340  if (!obj1 || !obj2)
1341  return 0;
1342 
1343  for (RenderObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor())
1344  for (RenderObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor())
1345  if (currObj1 == currObj2)
1346  return currObj1;
1347 
1348  return 0;
1349 }
1350 
13511338void RenderLayer::updateHoverActiveState(RenderObject::NodeInfo& info)
13521339{
13531340 // We don't update :hover/:active state when the info is marked as readonly.

@@void RenderLayer::updateHoverActiveState
13551342 return;
13561343
13571344 DocumentImpl* doc = renderer()->document();
1358  if (!doc) return;
 1345 if (!doc)
 1346 return;
13591347
 1348 NodeImpl* newHoverNode = info.innerNode();
13601349 NodeImpl* activeNode = doc->activeNode();
1361  if (activeNode && !info.active()) {
1362  // We are clearing the :active chain because the mouse has been released.
1363  for (RenderObject* curr = activeNode->renderer(); curr; curr = curr->parent()) {
1364  if (curr->element() && !curr->isText())
1365  curr->element()->setInActiveChain(false);
1366  }
1367  doc->setActiveNode(0);
1368  } else {
1369  NodeImpl* newActiveNode = info.innerNode();
1370  if (!activeNode && newActiveNode && info.active()) {
1371  // We are setting the :active chain and freezing it. If future moves happen, they
1372  // will need to reference this chain.
1373  for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) {
1374  if (curr->element() && !curr->isText()) {
1375  curr->element()->setInActiveChain(true);
1376  }
1377  }
1378  doc->setActiveNode(newActiveNode);
1379  }
1380  }
1381 
1382  // If the mouse is down and if this is a mouse move event, we want to restrict changes in
1383  // :hover/:active to only apply to elements that are in the :active chain that we froze
1384  // at the time the mouse went down.
1385  bool mustBeInActiveChain = info.active() && info.mouseMove();
13861350
1387  // Check to see if the hovered node has changed. If not, then we don't need to
1388  // do anything.
1389  DOM::NodeImpl* oldHoverNode = doc->hoverNode();
1390  DOM::NodeImpl* newHoverNode = info.innerNode();
 1351 if (activeNode && !info.active())
 1352 doc->setActiveNode(0);
 1353 else if (!activeNode && newHoverNode && info.active())
 1354 doc->setActiveNode(newHoverNode);
13911355
1392  // Update our current hover node.
13931356 doc->setHoverNode(newHoverNode);
1394 
1395  // We have two different objects. Fetch their renderers.
1396  RenderObject* oldHoverObj = oldHoverNode ? oldHoverNode->renderer() : 0;
1397  RenderObject* newHoverObj = newHoverNode ? newHoverNode->renderer() : 0;
1398 
1399  // Locate the common ancestor render object for the two renderers.
1400  RenderObject* ancestor = commonAncestor(oldHoverObj, newHoverObj);
1401 
1402  if (oldHoverObj != newHoverObj) {
1403  // The old hover path only needs to be cleared up to (and not including) the common ancestor;
1404  for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
1405  if (curr->element() && !curr->isText() && (!mustBeInActiveChain || curr->element()->inActiveChain())) {
1406  curr->element()->setActive(false);
1407  curr->element()->setHovered(false);
1408  }
1409  }
1410  }
1411 
1412  // Now set the hover state for our new object up to the root.
1413  for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) {
1414  if (curr->element() && !curr->isText() && (!mustBeInActiveChain || curr->element()->inActiveChain())) {
1415  curr->element()->setActive(info.active());
1416  curr->element()->setHovered(true);
1417  }
1418  }
14191357}
14201358
14211359// Helpers for the sorting of layers by z-index.
13191

WebCore/rendering/render_object.h

@@public:
333333 * positioned elements
334334 */
335335 RenderObject *container() const;
336  RenderObject* hoverAncestor() const;
337336
338337 virtual void markAllDescendantsWithFloatsForLayout(RenderObject* floatToRemove = 0);
339338 void markContainingBlocksForLayout();
13191

WebCore/rendering/render_object.cpp

@@RenderObject *RenderObject::container()
19931993 return o;
19941994}
19951995
1996 // This code has been written to anticipate the addition of CSS3-::outside and ::inside generated
1997 // content (and perhaps XBL). That's why it uses the render tree and not the DOM tree.
1998 RenderObject* RenderObject::hoverAncestor() const
1999 {
2000  return (!isInline() && continuation()) ? continuation() : parent();
2001 }
2002 
20031996bool RenderObject::isSelectionBorder() const
20041997{
20051998 SelectionState st = selectionState();
20061999 return st == SelectionStart || st == SelectionEnd || st == SelectionBoth;
20072000}
20082001
2009 
20102002void RenderObject::removeFromObjectLists()
20112003{
20122004 if (isFloating()) {
13191

WebCore/dom/DocumentImpl.h

@@public:
359359 NodeImpl* hoverNode() const { return m_hoverNode.get(); }
360360 void setHoverNode(PassRefPtr<NodeImpl>);
361361 void hoveredNodeDetached(NodeImpl*);
362  void activeChainNodeDetached(NodeImpl*);
363362
364363 NodeImpl* activeNode() const { return m_activeNode.get(); }
365364 void setActiveNode(PassRefPtr<NodeImpl>);
 365 void activeChainNodeDetached(NodeImpl*);
 366
 367 void trimHoverActiveChainsToRenderTree();
366368
367369 // Updates for :target (CSS3 selector).
368370 void setCSSTarget(NodeImpl*);
13191

WebCore/dom/DocumentImpl.cpp

@@void DocumentImpl::recalcStyleSelector()
19221922 m_styleSelectorDirty = false;
19231923}
19241924
 1925static NodeImpl* commonAncestor(NodeImpl* node1, NodeImpl* node2)
 1926{
 1927 if (!node1 || !node2)
 1928 return 0;
 1929
 1930 for (NodeImpl* currNode1 = node1; currNode1; currNode1 = currNode1->parent())
 1931 for (NodeImpl* currNode2 = node2; currNode2; currNode2 = currNode2->parent())
 1932 if (currNode1 == currNode2)
 1933 return currNode1;
 1934
 1935 return 0;
 1936}
 1937
19251938void DocumentImpl::setHoverNode(PassRefPtr<NodeImpl> newHoverNode)
19261939{
 1940 NodeImpl* oldHoverNode = m_hoverNode.get();
 1941 for (NodeImpl* curr = newHoverNode.get(); curr; curr = curr->parent()) {
 1942 if (!curr->isTextNode() && (!m_activeNode || curr->inActiveChain())) {
 1943 curr->setHovered(true);
 1944 curr->setActive(m_activeNode);
 1945 }
 1946 }
 1947 NodeImpl* ancestor = commonAncestor(oldHoverNode, newHoverNode.get());
 1948 for (NodeImpl* curr = oldHoverNode; curr != ancestor; curr = curr->parent()) {
 1949 if (!curr->isTextNode() && (!m_activeNode || curr->inActiveChain())) {
 1950 curr->setHovered(false);
 1951 curr->setActive(false);
 1952 }
 1953 }
19271954 m_hoverNode = newHoverNode;
19281955}
19291956
19301957void DocumentImpl::setActiveNode(PassRefPtr<NodeImpl> newActiveNode)
19311958{
 1959 NodeImpl* oldActiveNode = m_activeNode.get();
 1960 for (NodeImpl* curr = newActiveNode.get(); curr; curr = curr->parent()) {
 1961 if (!curr->isTextNode())
 1962 curr->setInActiveChain(true);
 1963 }
 1964 NodeImpl* ancestor = commonAncestor(oldActiveNode, newActiveNode.get());
 1965 for (NodeImpl* curr = oldActiveNode; curr != ancestor; curr = curr->parent()) {
 1966 if (!curr->isTextNode())
 1967 curr->setInActiveChain(false);
 1968 }
19321969 m_activeNode = newActiveNode;
19331970}
19341971

@@void DocumentImpl::activeChainNodeDetach
19541991 m_activeNode = m_activeNode->parent();
19551992}
19561993
 1994void DocumentImpl::trimHoverActiveChainsToRenderTree()
 1995{
 1996 NodeImpl *n;
 1997 for (n = m_hoverNode.get(); n && !n->renderer(); n = n->parent()) {
 1998 if (!n->isTextNode())
 1999 n->setHovered(false);
 2000 }
 2001 m_hoverNode = n;
 2002 for (n = m_activeNode.get(); n && !n->renderer(); n = n->parent()) {
 2003 if (!n->isTextNode()) {
 2004 n->setInActiveChain(false);
 2005 n->setActive(false);
 2006 }
 2007 }
 2008 m_activeNode = n;
 2009}
 2010
19572011bool DocumentImpl::relinquishesEditingFocus(NodeImpl *node)
19582012{
19592013 assert(node);
13191

WebCore/dom/dom_elementimpl.cpp

@@void ElementImpl::recalcStyle( StyleChan
561561 newStyle->ref();
562562 StyleChange ch = diff( _style, newStyle );
563563 if (ch == Detach) {
564  if (attached()) detach();
 564 if (attached()) {
 565 RefPtr<NodeImpl> hoverNode = getDocument()->hoverNode();
 566 RefPtr<NodeImpl> activeNode = getDocument()->activeNode();
 567 detach();
 568 getDocument()->setActiveNode(activeNode);
 569 getDocument()->setHoverNode(hoverNode);
 570 }
565571 // ### Suboptimal. Style gets calculated again.
566572 attach();
 573 getDocument()->trimHoverActiveChainsToRenderTree();
567574 // attach recalulates the style for all children. No need to do it twice.
568575 setChanged( false );
569576 setHasChangedChild( false );
13191

WebCore/css/cssstyleselector.cpp

@@bool CSSStyleSelector::checkOneSelector(
13921392 if (strictParsing || isSubSelector || sel->relation() == CSSSelector::SubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
13931393 if (element == e && style)
13941394 style->setAffectedByHoverRules(true);
1395  if (e->renderer()) {
1396  if (element != e)
1397  e->renderer()->style()->setAffectedByHoverRules(true);
1398  if (e->hovered())
1399  return true;
1400  }
 1395 if (e->renderer() && element != e)
 1396 e->renderer()->style()->setAffectedByHoverRules(true);
 1397 if (e->hovered())
 1398 return true;
14011399 }
14021400 break;
14031401 }
13191

WebCore/page/FrameView.cpp

@@void FrameView::layoutTimerFired(Timer<F
10661066void FrameView::hoverTimerFired(Timer<FrameView>*)
10671067{
10681068 d->hoverTimer.stop();
1069  m_frame->document()->prepareMouseEvent(false, false, true, d->prevMouseX, d->prevMouseY, 0);
 1069 m_frame->document()->prepareMouseEvent(false, d->mousePressed, true, d->prevMouseX, d->prevMouseY, 0);
10701070}
10711071
10721072void FrameView::scheduleRelayout()
13191