Reverting autoscroll fix. I need to rework this a little.
[WebKit-https.git] / WebCore / rendering / RenderLayer.cpp
1 /*
2  * Copyright (C) 2003 Apple Computer, Inc.
3  *
4  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5  *
6  * Other contributors:
7  *   Robert O'Callahan <roc+@cs.cmu.edu>
8  *   David Baron <dbaron@fas.harvard.edu>
9  *   Christian Biesinger <cbiesinger@web.de>
10  *   Randall Jesup <rjesup@wgate.com>
11  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
12  *   Josh Soref <timeless@mac.com>
13  *   Boris Zbarsky <bzbarsky@mit.edu>
14  *
15  * This library is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU Lesser General Public
17  * License as published by the Free Software Foundation; either
18  * version 2.1 of the License, or (at your option) any later version.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  *
29  * Alternatively, the contents of this file may be used under the terms
30  * of either the Mozilla Public License Version 1.1, found at
31  * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
32  * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
33  * (the "GPL"), in which case the provisions of the MPL or the GPL are
34  * applicable instead of those above.  If you wish to allow use of your
35  * version of this file only under the terms of one of those two
36  * licenses (the MPL or the GPL) and not to allow others to use your
37  * version of this file under the LGPL, indicate your decision by
38  * deletingthe provisions above and replace them with the notice and
39  * other provisions required by the MPL or the GPL, as the case may be.
40  * If you do not delete the provisions above, a recipient may use your
41  * version of this file under any of the LGPL, the MPL or the GPL.
42  */
43
44 #include "config.h"
45 #include "RenderLayer.h"
46
47 #include "CSSPropertyNames.h"
48 #include "Document.h"
49 #include "EventNames.h"
50 #include "FloatRect.h"
51 #include "Frame.h"
52 #include "FrameTree.h"
53 #include "GraphicsContext.h"
54 #include "HTMLMarqueeElement.h"
55 #include "HTMLNames.h"
56 #include "OverflowEvent.h"
57 #include "PlatformMouseEvent.h"
58 #include "RenderArena.h"
59 #include "RenderInline.h"
60 #include "RenderTheme.h"
61 #include "RenderView.h"
62 #include "SelectionController.h"
63 #include "PlatformScrollBar.h" 
64
65 #ifdef SVG_SUPPORT
66 #include "SVGNames.h"
67 #endif
68
69 #define MIN_INTERSECT_FOR_REVEAL 32
70
71 using namespace std;
72
73 namespace WebCore {
74
75 using namespace EventNames;
76 using namespace HTMLNames;
77
78 #ifndef NDEBUG
79 static bool inRenderLayerDestroy;
80 #endif
81
82 const RenderLayer::ScrollAlignment RenderLayer::gAlignCenterIfNeeded = { RenderLayer::noScroll, RenderLayer::alignCenter, RenderLayer::alignToClosestEdge };
83 const RenderLayer::ScrollAlignment RenderLayer::gAlignToEdgeIfNeeded = { RenderLayer::noScroll, RenderLayer::alignToClosestEdge, RenderLayer::alignToClosestEdge };
84 const RenderLayer::ScrollAlignment RenderLayer::gAlignCenterAlways = { RenderLayer::alignCenter, RenderLayer::alignCenter, RenderLayer::alignCenter };
85 const RenderLayer::ScrollAlignment RenderLayer::gAlignTopAlways = { RenderLayer::alignTop, RenderLayer::alignTop, RenderLayer::alignTop };
86 const RenderLayer::ScrollAlignment RenderLayer::gAlignBottomAlways = { RenderLayer::alignBottom, RenderLayer::alignBottom, RenderLayer::alignBottom };
87
88 const int MinimumWidthWhileResizing = 100;
89 const int MinimumHeightWhileResizing = 40;
90
91 void* ClipRects::operator new(size_t sz, RenderArena* renderArena) throw()
92 {
93     return renderArena->allocate(sz);
94 }
95
96 void ClipRects::operator delete(void* ptr, size_t sz)
97 {
98     // Stash size where destroy can find it.
99     *(size_t *)ptr = sz;
100 }
101
102 void ClipRects::destroy(RenderArena* renderArena)
103 {
104     delete this;
105     
106     // Recover the size left there for us by operator delete and free the memory.
107     renderArena->free(*(size_t *)this, this);
108 }
109
110 RenderLayer::RenderLayer(RenderObject* object)
111 : m_object(object),
112 m_parent(0),
113 m_previous(0),
114 m_next(0),
115 m_first(0),
116 m_last(0),
117 m_repaintX(0),
118 m_repaintY(0),
119 m_relX(0),
120 m_relY(0),
121 m_x(0),
122 m_y(0),
123 m_width(0),
124 m_height(0),
125 m_scrollX(0),
126 m_scrollY(0),
127 m_scrollOriginX(0),
128 m_scrollLeftOverflow(0),
129 m_scrollWidth(0),
130 m_scrollHeight(0),
131 m_inResizeMode(false),
132 m_resizeCornerImage(0),
133 m_posZOrderList(0),
134 m_negZOrderList(0),
135 m_overflowList(0),
136 m_clipRects(0) ,
137 m_scrollDimensionsDirty(true),
138 m_zOrderListsDirty(true),
139 m_overflowListDirty(true),
140 m_isOverflowOnly(shouldBeOverflowOnly()),
141 m_usedTransparency(false),
142 m_inOverflowRelayout(false),
143 m_repaintOverflowOnResize(false),
144 m_overflowStatusDirty(true),
145 m_marquee(0)
146 {
147 }
148
149 RenderLayer::~RenderLayer()
150 {
151     destroyScrollbar(HorizontalScrollbar);
152     destroyScrollbar(VerticalScrollbar);
153
154     // Child layers will be deleted by their corresponding render objects, so
155     // we don't need to delete them ourselves.
156
157     delete m_resizeCornerImage;
158     delete m_posZOrderList;
159     delete m_negZOrderList;
160     delete m_overflowList;
161     delete m_marquee;
162     
163     // Make sure we have no lingering clip rects.
164     assert(!m_clipRects);
165 }
166
167 void RenderLayer::checkForRepaintOnResize()
168 {
169     m_repaintOverflowOnResize = m_object->selfNeedsLayout() || m_object->hasOverflowClip() && m_object->normalChildNeedsLayout();
170     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
171         child->checkForRepaintOnResize();
172 }
173
174 void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
175 {
176     if (doFullRepaint) {
177         m_object->repaint();
178         checkForRepaint = doFullRepaint = false;
179     }
180     
181     updateLayerPosition(); // For relpositioned layers or non-positioned layers,
182                            // we need to keep in sync, since we may have shifted relative
183                            // to our parent layer.
184
185     positionResizeControl();
186     if (m_hBar || m_vBar) {
187         // Need to position the scrollbars.
188         int x = 0;
189         int y = 0;
190         convertToLayerCoords(root(), x, y);
191         IntRect layerBounds = IntRect(x,y,width(),height());
192         positionScrollbars(layerBounds);
193     }
194
195     // FIXME: Child object could override visibility.
196     if (m_object->style()->visibility() == VISIBLE) {
197         int x, y;
198         m_object->absolutePosition(x, y);
199         IntRect newRect, newFullRect;
200         m_object->getAbsoluteRepaintRectIncludingFloats(newRect, newFullRect);
201         if (checkForRepaint) {
202             RenderView *c = m_object->view();
203             if (c && !c->printingMode()) {
204                 bool didMove = x != m_repaintX || y != m_repaintY;
205                 if (!didMove && !m_repaintOverflowOnResize)
206                     m_object->repaintAfterLayoutIfNeeded(m_repaintRect, m_fullRepaintRect);
207                 else if (didMove || newRect != m_repaintRect) {
208                     c->repaintViewRectangle(m_fullRepaintRect);
209                     c->repaintViewRectangle(newFullRect);
210                 }
211             }
212         }
213         m_repaintRect = newRect;
214         m_fullRepaintRect = newFullRect;
215         m_repaintX = x;
216         m_repaintY = y;
217     } else {
218         m_repaintRect = IntRect();
219         m_fullRepaintRect = IntRect();
220     }
221     
222     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
223         child->updateLayerPositions(doFullRepaint, checkForRepaint);
224         
225     // With all our children positioned, now update our marquee if we need to.
226     if (m_marquee)
227         m_marquee->updateMarqueePosition();
228 }
229
230 void RenderLayer::updateLayerPosition()
231 {
232     // Clear our cached clip rect information.
233     clearClipRect();
234
235     // The canvas is sized to the docWidth/Height over in RenderView::layout, so we
236     // don't need to ever update our layer position here.
237     if (renderer()->isRenderView())
238         return;
239     
240     int x = m_object->xPos();
241     int y = m_object->yPos() - m_object->borderTopExtra();
242
243     if (!m_object->isPositioned()) {
244         // We must adjust our position by walking up the render tree looking for the
245         // nearest enclosing object with a layer.
246         RenderObject* curr = m_object->parent();
247         while (curr && !curr->layer()) {
248             if (!curr->isTableRow()) {
249                 // Rows and cells share the same coordinate space (that of the section).
250                 // Omit them when computing our xpos/ypos.
251                 x += curr->xPos();
252                 y += curr->yPos();
253             }
254             curr = curr->parent();
255         }
256         y += curr->borderTopExtra();
257         if (curr->isTableRow()) {
258             // Put ourselves into the row coordinate space.
259             x -= curr->xPos();
260             y -= curr->yPos();
261         }
262     }
263
264     m_relX = m_relY = 0;
265     if (m_object->isRelPositioned()) {
266         m_relX = static_cast<RenderBox*>(m_object)->relativePositionOffsetX();
267         m_relY = static_cast<RenderBox*>(m_object)->relativePositionOffsetY();
268         x += m_relX; y += m_relY;
269     }
270     
271     // Subtract our parent's scroll offset.
272     if (m_object->isPositioned() && enclosingPositionedAncestor()) {
273         RenderLayer* positionedParent = enclosingPositionedAncestor();
274
275         // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
276         positionedParent->subtractScrollOffset(x, y);
277         
278         if (m_object->isPositioned() && positionedParent->renderer()->isRelPositioned() &&
279             positionedParent->renderer()->isInlineFlow()) {
280             // When we have an enclosing relpositioned inline, we need to add in the offset of the first line
281             // box from the rest of the content, but only in the cases where we know we're positioned
282             // relative to the inline itself.
283             RenderFlow* flow = static_cast<RenderFlow*>(positionedParent->renderer());
284             int sx = 0, sy = 0;
285             if (flow->firstLineBox()) {
286                 sx = flow->firstLineBox()->xPos();
287                 sy = flow->firstLineBox()->yPos();
288             }
289             else {
290                 sx = flow->staticX();
291                 sy = flow->staticY();
292             }
293             bool isInlineType = m_object->style()->isOriginalDisplayInlineType();
294             
295             if (!m_object->hasStaticX())
296                 x += sx;
297             
298             // This is not terribly intuitive, but we have to match other browsers.  Despite being a block display type inside
299             // an inline, we still keep our x locked to the left of the relative positioned inline.  Arguably the correct
300             // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers
301             // do.
302             if (m_object->hasStaticX() && !isInlineType)
303                 // Avoid adding in the left border/padding of the containing block twice.  Subtract it out.
304                 x += sx - (m_object->containingBlock()->borderLeft() + m_object->containingBlock()->paddingLeft());
305             
306             if (!m_object->hasStaticY())
307                 y += sy;
308         }
309     }
310     else if (parent())
311         parent()->subtractScrollOffset(x, y);
312     
313     setPos(x,y);
314
315     setWidth(m_object->width());
316     setHeight(m_object->height() + m_object->borderTopExtra() + m_object->borderBottomExtra());
317
318     if (!m_object->hasOverflowClip()) {
319         if (m_object->overflowWidth() > m_object->width())
320             setWidth(m_object->overflowWidth());
321         if (m_object->overflowHeight() > m_object->height())
322             setHeight(m_object->overflowHeight());
323     }
324 }
325
326 RenderLayer *RenderLayer::stackingContext() const
327 {
328     RenderLayer* curr = parent();
329     for ( ; curr && !curr->m_object->isRenderView() && !curr->m_object->isRoot() &&
330           curr->m_object->style()->hasAutoZIndex();
331           curr = curr->parent());
332     return curr;
333 }
334
335 RenderLayer*
336 RenderLayer::enclosingPositionedAncestor() const
337 {
338     RenderLayer* curr = parent();
339     for ( ; curr && !curr->m_object->isRenderView() && !curr->m_object->isRoot() &&
340          !curr->m_object->isPositioned() && !curr->m_object->isRelPositioned();
341          curr = curr->parent());
342          
343     return curr;
344 }
345
346 bool
347 RenderLayer::isTransparent() const
348 {
349 #ifdef SVG_SUPPORT
350     if (m_object->node()->namespaceURI() == SVGNames::svgNamespaceURI)
351         return false;
352 #endif
353     return m_object->isTransparent();
354 }
355
356 RenderLayer*
357 RenderLayer::transparentAncestor()
358 {
359     RenderLayer* curr = parent();
360     for ( ; curr && !curr->isTransparent(); curr = curr->parent());
361     return curr;
362 }
363
364 static IntRect transparencyClipBox(RenderLayer* l)
365 {
366     // FIXME: Although this completely ignores clipping, we ultimately intersect with the
367     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
368     // would be better to respect clips.
369     IntRect clipRect = l->absoluteBoundingBox();
370     
371     // Note: we don't have to walk z-order lists since transparent elements always establish
372     // a stacking context.  This means we can just walk the layer tree directly. 
373     for (RenderLayer* curr = l->firstChild(); curr; curr = curr->nextSibling()) {
374         // Transparent children paint in a different transparency layer, and so we exclude them.
375         if (!curr->isTransparent())
376             clipRect.unite(curr->absoluteBoundingBox());
377     }
378     
379     return clipRect;
380 }
381
382 void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const IntRect& paintDirtyRect)
383 {
384     if (p->paintingDisabled() || (isTransparent() && m_usedTransparency))
385         return;
386     
387     RenderLayer* ancestor = transparentAncestor();
388     if (ancestor)
389         ancestor->beginTransparencyLayers(p, paintDirtyRect);
390     
391     if (isTransparent()) {
392         m_usedTransparency = true;
393         IntRect clipRect = transparencyClipBox(this);
394         clipRect.intersect(paintDirtyRect);
395         p->save();
396         p->clip(clipRect);
397         p->beginTransparencyLayer(renderer()->opacity());
398     }
399 }
400
401 void* RenderLayer::operator new(size_t sz, RenderArena* renderArena) throw()
402 {
403     return renderArena->allocate(sz);
404 }
405
406 void RenderLayer::operator delete(void* ptr, size_t sz)
407 {
408     assert(inRenderLayerDestroy);
409     
410     // Stash size where destroy can find it.
411     *(size_t *)ptr = sz;
412 }
413
414 void RenderLayer::destroy(RenderArena* renderArena)
415 {
416 #ifndef NDEBUG
417     inRenderLayerDestroy = true;
418 #endif
419     delete this;
420 #ifndef NDEBUG
421     inRenderLayerDestroy = false;
422 #endif
423     
424     // Recover the size left there for us by operator delete and free the memory.
425     renderArena->free(*(size_t *)this, this);
426 }
427
428 void RenderLayer::addChild(RenderLayer *child, RenderLayer* beforeChild)
429 {
430     RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
431     if (prevSibling) {
432         child->setPreviousSibling(prevSibling);
433         prevSibling->setNextSibling(child);
434     }
435     else
436         setFirstChild(child);
437
438     if (beforeChild) {
439         beforeChild->setPreviousSibling(child);
440         child->setNextSibling(beforeChild);
441     }
442     else
443         setLastChild(child);
444    
445     child->setParent(this);
446
447     if (child->isOverflowOnly())
448         dirtyOverflowList();
449     else {
450         // Dirty the z-order list in which we are contained.  The stackingContext() can be null in the
451         // case where we're building up generated content layers.  This is ok, since the lists will start
452         // off dirty in that case anyway.
453         RenderLayer* stackingContext = child->stackingContext();
454         if (stackingContext)
455             stackingContext->dirtyZOrderLists();
456     }
457 }
458
459 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
460 {
461     // remove the child
462     if (oldChild->previousSibling())
463         oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
464     if (oldChild->nextSibling())
465         oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
466
467     if (m_first == oldChild)
468         m_first = oldChild->nextSibling();
469     if (m_last == oldChild)
470         m_last = oldChild->previousSibling();
471
472     if (oldChild->isOverflowOnly())
473         dirtyOverflowList();
474     else { 
475         // Dirty the z-order list in which we are contained.  When called via the
476         // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
477         // from the main layer tree, so we need to null-check the |stackingContext| value.
478         RenderLayer* stackingContext = oldChild->stackingContext();
479         if (stackingContext)
480             stackingContext->dirtyZOrderLists();
481     }
482
483     oldChild->setPreviousSibling(0);
484     oldChild->setNextSibling(0);
485     oldChild->setParent(0);
486     
487     return oldChild;
488 }
489
490 void RenderLayer::removeOnlyThisLayer()
491 {
492     if (!m_parent)
493         return;
494     
495     // Dirty the clip rects.
496     clearClipRects();
497
498     // Remove us from the parent.
499     RenderLayer* parent = m_parent;
500     RenderLayer* nextSib = nextSibling();
501     parent->removeChild(this);
502     
503     // Now walk our kids and reattach them to our parent.
504     RenderLayer* current = m_first;
505     while (current) {
506         RenderLayer* next = current->nextSibling();
507         removeChild(current);
508         parent->addChild(current, nextSib);
509         current->updateLayerPositions();
510         current = next;
511     }
512     
513     destroy(renderer()->renderArena());
514 }
515
516 void RenderLayer::insertOnlyThisLayer()
517 {
518     if (!m_parent && renderer()->parent()) {
519         // We need to connect ourselves when our renderer() has a parent.
520         // Find our enclosingLayer and add ourselves.
521         RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();
522         if (parentLayer)
523             parentLayer->addChild(this, 
524                                   renderer()->parent()->findNextLayer(parentLayer, renderer()));
525     }
526     
527     // Remove all descendant layers from the hierarchy and add them to the new position.
528     for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling())
529         curr->moveLayers(m_parent, this);
530         
531     // Clear out all the clip rects.
532     clearClipRects();
533 }
534
535 void 
536 RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const
537 {
538     if (ancestorLayer == this)
539         return;
540         
541     if (m_object->style()->position() == FixedPosition) {
542         // Add in the offset of the view.  We can obtain this by calling
543         // absolutePosition() on the RenderView.
544         int xOff, yOff;
545         m_object->absolutePosition(xOff, yOff, true);
546         x += xOff;
547         y += yOff;
548         return;
549     }
550  
551     RenderLayer* parentLayer;
552     if (m_object->style()->position() == AbsolutePosition)
553         parentLayer = enclosingPositionedAncestor();
554     else
555         parentLayer = parent();
556     
557     if (!parentLayer) return;
558     
559     parentLayer->convertToLayerCoords(ancestorLayer, x, y);
560
561     x += xPos();
562     y += yPos();
563 }
564
565 void
566 RenderLayer::scrollOffset(int& x, int& y)
567 {
568     x += scrollXOffset() + m_scrollLeftOverflow;
569     y += scrollYOffset();
570 }
571
572 void
573 RenderLayer::subtractScrollOffset(int& x, int& y)
574 {
575     x -= scrollXOffset() + m_scrollLeftOverflow;
576     y -= scrollYOffset();
577 }
578
579 void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repaint)
580 {
581     if (renderer()->style()->overflowX() != OMARQUEE) {
582         if (x < 0) x = 0;
583         if (y < 0) y = 0;
584     
585         // Call the scrollWidth/Height functions so that the dimensions will be computed if they need
586         // to be (for overflow:hidden blocks).
587         int maxX = scrollWidth() - m_object->clientWidth();
588         int maxY = scrollHeight() - m_object->clientHeight();
589         
590         if (x > maxX) x = maxX;
591         if (y > maxY) y = maxY;
592     }
593     
594     // FIXME: Eventually, we will want to perform a blit.  For now never
595     // blit, since the check for blitting is going to be very
596     // complicated (since it will involve testing whether our layer
597     // is either occluded by another layer or clipped by an enclosing
598     // layer or contains fixed backgrounds, etc.).
599     m_scrollX = x - m_scrollOriginX;
600     m_scrollY = y;
601
602     // Update the positions of our child layers.
603     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
604         child->updateLayerPositions(false, false);
605     
606     RenderView* view = renderer()->view();
607     if (view) {
608 #if PLATFORM(MAC)
609         // Update dashboard regions, scrolling may change the clip of a
610         // particular region.
611         view->frameView()->updateDashboardRegions();
612 #endif
613
614         m_object->view()->updateWidgetPositions();
615     }
616
617     // Just schedule a full repaint of our object.
618     if (repaint)
619         m_object->repaint();
620     
621     if (updateScrollbars) {
622         if (m_hBar)
623             m_hBar->setValue(scrollXOffset());
624         if (m_vBar)
625             m_vBar->setValue(m_scrollY);
626     }
627
628     // Fire the scroll DOM event.
629     EventTargetNodeCast(m_object->element())->dispatchHTMLEvent(scrollEvent, true, false);
630 }
631
632 void RenderLayer::scrollRectToVisible(const IntRect &rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
633 {
634     RenderLayer* parentLayer = 0;
635     IntRect newRect = rect;
636     int xOffset = 0, yOffset = 0;
637     
638     if (m_object->hasOverflowClip()) {
639         IntRect layerBounds = IntRect(xPos() + scrollXOffset(), yPos() + scrollYOffset(), 
640                                       width() - verticalScrollbarWidth(), height() - horizontalScrollbarHeight());
641         IntRect exposeRect = IntRect(rect.x() + scrollXOffset(), rect.y() + scrollYOffset(), rect.width(), rect.height());
642         IntRect r = getRectToExpose(layerBounds, exposeRect, alignX, alignY);
643         
644         xOffset = r.x() - xPos();
645         yOffset = r.y() - yPos();
646         // Adjust offsets if they're outside of the allowable range.
647         xOffset = max(0, min(scrollWidth() - width(), xOffset));
648         yOffset = max(0, min(scrollHeight() - height(), yOffset));
649         
650         if (xOffset != scrollXOffset() || yOffset != scrollYOffset()) {
651             int diffX = scrollXOffset();
652             int diffY = scrollYOffset();
653             scrollToOffset(xOffset, yOffset);
654             // FIXME: At this point a scroll event fired, which could have deleted this layer.
655             // Need to handle this case.
656             diffX = scrollXOffset() - diffX;
657             diffY = scrollYOffset() - diffY;
658             newRect.setX(rect.x() - diffX);
659             newRect.setY(rect.y() - diffY);
660         }
661     
662         if (m_object->parent())
663             parentLayer = m_object->parent()->enclosingLayer();
664     } else {
665         FrameView* view = m_object->document()->view();
666         if (view) {
667             IntRect viewRect = enclosingIntRect(view->visibleContentRect());
668             IntRect r = getRectToExpose(viewRect, rect, alignX, alignY);
669             
670             xOffset = r.x();
671             yOffset = r.y();
672             // Adjust offsets if they're outside of the allowable range.
673             xOffset = max(0, min(view->contentsWidth(), xOffset));
674             yOffset = max(0, min(view->contentsHeight(), yOffset));
675
676             if (m_object->document() && m_object->document()->ownerElement() && m_object->document()->ownerElement()->renderer()) {
677                 view->setContentsPos(xOffset, yOffset);
678                 parentLayer = m_object->document()->ownerElement()->renderer()->enclosingLayer();
679                 newRect.setX(rect.x() - view->contentsX() + view->x());
680                 newRect.setY(rect.y() - view->contentsY() + view->y());
681             } else {
682                 // If this is the outermost view that RenderLayer needs to scroll, then we should scroll the view recursively
683                 // Other apps, like Mail, rely on this feature.
684                 view->scrollPointRecursively(xOffset, yOffset);
685             }
686         }
687     }
688     
689     if (parentLayer)
690         parentLayer->scrollRectToVisible(newRect, alignX, alignY);
691 }
692
693 IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
694 {
695     // Determine the appropriate X behavior.
696     ScrollBehavior scrollX;
697     IntRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
698     int intersectWidth = intersection(visibleRect, exposeRectX).width();
699     if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
700         // If the rectangle is fully visible, use the specified visible behavior.
701         // If the rectangle is partially visible, but over a certain threshold,
702         // then treat it as fully visible to avoid unnecessary horizontal scrolling
703         scrollX = getVisibleBehavior(alignX);
704     else if (intersectWidth == visibleRect.width()) {
705         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
706         scrollX = getVisibleBehavior(alignX);
707         if (scrollX == alignCenter)
708             scrollX = noScroll;
709     } else if (intersectWidth > 0)
710         // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
711         scrollX = getPartialBehavior(alignX);
712     else
713         scrollX = getHiddenBehavior(alignX);
714     // If we're trying to align to the closest edge, and the exposeRect is further right
715     // than the visibleRect, and not bigger than the visible area, then align with the right.
716     if (scrollX == alignToClosestEdge && exposeRect.right() > visibleRect.right() && exposeRect.width() < visibleRect.width())
717         scrollX = alignRight;
718
719     // Given the X behavior, compute the X coordinate.
720     int x;
721     if (scrollX == noScroll) 
722         x = visibleRect.x();
723     else if (scrollX == alignRight)
724         x = exposeRect.right() - visibleRect.width();
725     else if (scrollX == alignCenter)
726         x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
727     else
728         x = exposeRect.x();
729
730     // Determine the appropriate Y behavior.
731     ScrollBehavior scrollY;
732     IntRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
733     int intersectHeight = intersection(visibleRect, exposeRectY).height();
734     if (intersectHeight == exposeRect.height())
735         // If the rectangle is fully visible, use the specified visible behavior.
736         scrollY = getVisibleBehavior(alignY);
737     else if (intersectHeight == visibleRect.height()) {
738         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
739         scrollY = getVisibleBehavior(alignY);
740         if (scrollY == alignCenter)
741             scrollY = noScroll;
742     } else if (intersectHeight > 0)
743         // If the rectangle is partially visible, use the specified partial behavior
744         scrollY = getPartialBehavior(alignY);
745     else
746         scrollY = getHiddenBehavior(alignY);
747     // If we're trying to align to the closest edge, and the exposeRect is further down
748     // than the visibleRect, and not bigger than the visible area, then align with the bottom.
749     if (scrollY == alignToClosestEdge && exposeRect.bottom() > visibleRect.bottom() && exposeRect.height() < visibleRect.height())
750         scrollY = alignBottom;
751
752     // Given the Y behavior, compute the Y coordinate.
753     int y;
754     if (scrollY == noScroll) 
755         y = visibleRect.y();
756     else if (scrollY == alignBottom)
757         y = exposeRect.bottom() - visibleRect.height();
758     else if (scrollY == alignCenter)
759         y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
760     else
761         y = exposeRect.y();
762
763     return IntRect(IntPoint(x, y), visibleRect.size());
764 }
765
766 void RenderLayer::autoscroll()
767 {    
768     int xOffset = scrollXOffset();
769     int yOffset = scrollYOffset();
770
771     // Get the rectangle for the extent of the selection
772     Selection selection(renderer()->document()->frame()->selectionController()->selection());
773     IntRect extentRect = VisiblePosition(selection.extent()).caretRect();
774     extentRect.move(xOffset, yOffset);
775
776     IntRect bounds = IntRect(xPos() + xOffset, yPos() + yOffset, width() - verticalScrollbarWidth(), height() - horizontalScrollbarHeight());
777     
778     // Calculate how much the layer should scroll horizontally.
779     int diffX = 0;
780     if (extentRect.right() > bounds.right())
781         diffX = extentRect.right() - bounds.right();
782     else if (extentRect.x() < bounds.x())
783         diffX = extentRect.x() - bounds.x();
784         
785     // Calculate how much the layer should scroll vertically.
786     int diffY = 0;
787     if (extentRect.bottom() > bounds.bottom())
788         diffY = extentRect.bottom() - bounds.bottom();
789     else if (extentRect.y() < bounds.y())
790         diffY = extentRect.y() - bounds.y();
791
792     scrollToOffset(xOffset + diffX, yOffset + diffY);
793 }
794
795 void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& offsetFromResizeCorner)
796 {
797     if (!inResizeMode() || !renderer()->hasOverflowClip() || m_object->style()->resize() == RESIZE_NONE)
798         return;
799
800     if (!m_object->document()->frame()->view()->mousePressed())
801         return;
802
803     // FIXME Radar 4118559: This behaves very oddly for textareas that are in blocks with right-aligned text; you have
804     // to drag the bottom-right corner to make the bottom-left corner move.
805     // FIXME Radar 4118564: ideally we'd autoscroll the window as necessary to keep the point under
806     // the cursor in view.
807
808     IntPoint currentPoint = m_object->document()->view()->windowToContents(evt.pos());
809     currentPoint += offsetFromResizeCorner;
810
811     int x;
812     int y;
813     m_object->absolutePosition(x, y);
814     int right = x + m_object->width();
815     int bottom = y + m_object->height();
816     int diffWidth =  max(currentPoint.x() - right, min(0, MinimumWidthWhileResizing - m_object->width()));
817     int diffHeight = max(currentPoint.y() - bottom, min(0, MinimumHeightWhileResizing - m_object->height()));
818     
819     ExceptionCode ec = 0;
820     // Set the width and height for the shadow ancestor node.  This is necessary for textareas since the resizable layer is on the inner div.
821     // For non-shadow content, this will set the width and height on the original node.
822     RenderObject* renderer = m_object->node()->shadowAncestorNode()->renderer();
823     if (diffWidth && (m_object->style()->resize() == RESIZE_HORIZONTAL || m_object->style()->resize() == RESIZE_BOTH)) {
824         CSSStyleDeclaration* style = static_cast<Element*>(m_object->node()->shadowAncestorNode())->style();
825         if (renderer->element() && renderer->element()->isControl()) {
826             style->setProperty(CSS_PROP_MARGIN_LEFT, String::number(renderer->marginLeft()) + "px", false, ec);
827             style->setProperty(CSS_PROP_MARGIN_RIGHT, String::number(renderer->marginRight()) + "px", false, ec);
828         }
829         int baseWidth = renderer->width() - (renderer->style()->boxSizing() == BORDER_BOX ? 0 : renderer->borderLeft() + renderer->paddingLeft() + renderer->borderRight() + renderer->paddingRight());
830         style->setProperty(CSS_PROP_WIDTH, String::number(baseWidth + diffWidth) + "px", false, ec);
831     }
832
833     if (diffHeight && (m_object->style()->resize() == RESIZE_VERTICAL || m_object->style()->resize() == RESIZE_BOTH)) {
834         CSSStyleDeclaration* style = static_cast<Element*>(m_object->node()->shadowAncestorNode())->style();
835         if (renderer->element() && renderer->element()->isControl()) {
836             style->setProperty(CSS_PROP_MARGIN_TOP, String::number(renderer->marginTop()) + "px", false, ec);
837             style->setProperty(CSS_PROP_MARGIN_BOTTOM, String::number(renderer->marginBottom()) + "px", false, ec);
838         }
839         int baseHeight = renderer->height() - (renderer->style()->boxSizing() == BORDER_BOX ? 0 : renderer->borderTop() + renderer->paddingTop() + renderer->borderBottom() + renderer->paddingBottom());
840         style->setProperty(CSS_PROP_HEIGHT, String::number(baseHeight + diffHeight) + "px", false, ec);
841     }
842     
843     ASSERT(ec == 0);
844
845     if (m_object->style()->resize() != RESIZE_NONE) {
846         m_object->setNeedsLayout(true);
847         m_object->node()->shadowAncestorNode()->renderer()->setNeedsLayout(true);
848         m_object->document()->updateLayout();
849     }
850 }
851
852 PlatformScrollbar* RenderLayer::horizontaScrollbarWidget() const
853 {
854     if (m_hBar && m_hBar->isWidget())
855         return static_cast<PlatformScrollbar*>(m_hBar.get());
856     return 0;
857 }
858
859 PlatformScrollbar* RenderLayer::verticalScrollbarWidget() const
860 {
861     if (m_vBar && m_vBar->isWidget())
862         return static_cast<PlatformScrollbar*>(m_vBar.get());
863     return 0;
864 }
865
866 void RenderLayer::valueChanged(Scrollbar*)
867 {
868     // Update scroll position from scrollbars.
869
870     bool needUpdate = false;
871     int newX = scrollXOffset();
872     int newY = m_scrollY;
873     
874     if (m_hBar) {
875         newX = m_hBar->value();
876         if (newX != scrollXOffset())
877            needUpdate = true;
878     }
879
880     if (m_vBar) {
881         newY = m_vBar->value();
882         if (newY != m_scrollY)
883            needUpdate = true;
884     }
885
886     if (needUpdate)
887         scrollToOffset(newX, newY, false);
888 }
889
890 PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
891 {
892     if (Scrollbar::hasPlatformScrollbars()) {
893         RefPtr<PlatformScrollbar> widget = new PlatformScrollbar(this, orientation, RegularScrollbar);
894         m_object->element()->document()->view()->addChild(widget.get());
895         return widget.release();
896     }
897     
898     // FIXME: Create scrollbars using the engine.
899     return 0;
900 }
901
902 void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
903 {
904     RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
905     if (scrollbar) {
906         if (scrollbar->isWidget())
907             static_cast<PlatformScrollbar*>(scrollbar.get())->removeFromParent();
908
909         // FIXME: Destroy the engine scrollbar.
910         scrollbar = 0;
911     }
912 }
913
914 void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
915 {
916     if (hasScrollbar == (m_hBar != 0))
917         return;
918
919     if (hasScrollbar)
920         m_hBar = createScrollbar(HorizontalScrollbar);
921     else
922         destroyScrollbar(HorizontalScrollbar);
923
924 #if PLATFORM(MAC)
925     // Force an update since we know the scrollbars have changed things.
926     if (m_object->document()->hasDashboardRegions())
927         m_object->document()->setDashboardRegionsDirty(true);
928 #endif
929
930 }
931
932 void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
933 {
934     if (hasScrollbar == (m_vBar != 0))
935         return;
936
937     if (hasScrollbar)
938         m_vBar = createScrollbar(VerticalScrollbar);
939     else
940         destroyScrollbar(VerticalScrollbar);
941
942 #if PLATFORM(MAC)
943     // Force an update since we know the scrollbars have changed things.
944     if (m_object->document()->hasDashboardRegions())
945         m_object->document()->setDashboardRegionsDirty(true);
946 #endif
947
948 }
949
950 int RenderLayer::verticalScrollbarWidth() const
951 {
952     if (!m_vBar)
953         return 0;
954     return m_vBar->width();
955 }
956
957 int RenderLayer::horizontalScrollbarHeight() const
958 {
959     if (!m_hBar)
960         return 0;
961     return m_hBar->height();
962 }
963
964 bool RenderLayer::isPointInResizeControl(const IntPoint& p)
965 {
966     return resizeControlRect().contains(IntRect(p, IntSize()));
967 }
968
969 IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& p) const
970 {
971     // Currently the resize corner is always the bottom right corner
972     int x = width();
973     int y = height();
974     convertToLayerCoords(root(), x, y);
975     return IntSize(x - p.x(), y - p.y());
976 }
977
978 void RenderLayer::positionResizeControl()
979 {
980     if (m_object->hasOverflowClip() && m_object->style()->resize() != RESIZE_NONE) {
981         // FIXME: needs to be updated for RTL.
982         int x = 0;
983         int y = 0;
984         convertToLayerCoords(root(), x, y);
985         // FIXME: get the potential scrollbar size from the theme
986         int scrollbarSize = 15;
987         setResizeControlRect(IntRect(x + width() - scrollbarSize - m_object->style()->borderRightWidth() - 1, 
988                              y + height() - scrollbarSize - m_object->style()->borderBottomWidth() - 1, scrollbarSize, scrollbarSize));
989     }
990 }
991
992 void
993 RenderLayer::positionScrollbars(const IntRect& absBounds)
994 {
995     int resizeControlSize = max(resizeControlRect().height(), 0);
996     if (m_vBar)
997         m_vBar->setRect(IntRect(absBounds.right() - m_object->borderRight() - m_vBar->width(),
998                                 absBounds.y() + m_object->borderTop(),
999                                 m_vBar->width(),
1000                                 absBounds.height() - (m_object->borderTop() + m_object->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize)));
1001
1002     resizeControlSize = max(resizeControlRect().width(), 0);
1003     if (m_hBar)
1004         m_hBar->setRect(IntRect(absBounds.x() + m_object->borderLeft(),
1005                                 absBounds.bottom() - m_object->borderBottom() - m_hBar->height(),
1006                                 absBounds.width() - (m_object->borderLeft() + m_object->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
1007                                 m_hBar->height()));
1008 }
1009
1010 int RenderLayer::scrollWidth()
1011 {
1012     if (m_scrollDimensionsDirty)
1013         computeScrollDimensions();
1014     return m_scrollWidth;
1015 }
1016
1017 int RenderLayer::scrollHeight()
1018 {
1019     if (m_scrollDimensionsDirty)
1020         computeScrollDimensions();
1021     return m_scrollHeight;
1022 }
1023
1024 void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
1025 {
1026     m_scrollDimensionsDirty = false;
1027     
1028     bool ltr = m_object->style()->direction() == LTR;
1029
1030     int clientWidth = m_object->clientWidth();
1031     int clientHeight = m_object->clientHeight();
1032
1033     m_scrollLeftOverflow = ltr ? 0 : min(0, m_object->leftmostPosition(true, false) - m_object->borderLeft());
1034
1035     int rightPos = ltr ?
1036                     m_object->rightmostPosition(true, false) - m_object->borderLeft() :
1037                     clientWidth - m_scrollLeftOverflow;
1038     int bottomPos = m_object->lowestPosition(true, false) - m_object->borderTop();
1039
1040     m_scrollWidth = max(rightPos, clientWidth);
1041     m_scrollHeight = max(bottomPos, clientHeight);
1042     
1043     m_scrollOriginX = ltr ? 0 : m_scrollWidth - clientWidth;
1044
1045     if (needHBar)
1046         *needHBar = rightPos > clientWidth;
1047     if (needVBar)
1048         *needVBar = bottomPos > clientHeight;
1049 }
1050
1051 void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
1052 {
1053     if (m_overflowStatusDirty) {
1054         m_horizontalOverflow = horizontalOverflow;
1055         m_verticalOverflow = verticalOverflow;
1056         m_overflowStatusDirty = false;
1057         
1058         return;
1059     }
1060     
1061     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
1062     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
1063     
1064     if (horizontalOverflowChanged || verticalOverflowChanged) {
1065         m_horizontalOverflow = horizontalOverflow;
1066         m_verticalOverflow = verticalOverflow;
1067         
1068         m_object->element()->document()->frame()->view()->scheduleEvent(new OverflowEvent(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow),
1069                                                                         EventTargetNodeCast(m_object->element()), true);
1070     }
1071 }
1072
1073 void
1074 RenderLayer::updateScrollInfoAfterLayout()
1075 {
1076     m_scrollDimensionsDirty = true;
1077
1078     bool horizontalOverflow, verticalOverflow;
1079     computeScrollDimensions(&horizontalOverflow, &verticalOverflow);
1080
1081     if (m_object->style()->overflowX() != OMARQUEE) {
1082         // Layout may cause us to be in an invalid scroll position.  In this case we need
1083         // to pull our scroll offsets back to the max (or push them up to the min).
1084         int newX = max(0, min(scrollXOffset(), scrollWidth() - m_object->clientWidth()));
1085         int newY = max(0, min(m_scrollY, scrollHeight() - m_object->clientHeight()));
1086         if (newX != scrollXOffset() || newY != m_scrollY)
1087             scrollToOffset(newX, newY);
1088         // FIXME: At this point a scroll event fired, which could have deleted this layer.
1089         // Need to handle this case.
1090     }
1091
1092     bool haveHorizontalBar = m_hBar;
1093     bool haveVerticalBar = m_vBar;
1094     
1095     // overflow:scroll should just enable/disable.
1096     if (m_object->style()->overflowX() == OSCROLL)
1097         m_hBar->setEnabled(horizontalOverflow);
1098     if (m_object->style()->overflowY() == OSCROLL)
1099         m_vBar->setEnabled(verticalOverflow);
1100
1101     // A dynamic change from a scrolling overflow to overflow:hidden means we need to get rid of any
1102     // scrollbars that may be present.
1103     if (m_object->style()->overflowX() == OHIDDEN && haveHorizontalBar)
1104         setHasHorizontalScrollbar(false);
1105     if (m_object->style()->overflowY() == OHIDDEN && haveVerticalBar)
1106         setHasVerticalScrollbar(false);
1107     
1108     // overflow:auto may need to lay out again if scrollbars got added/removed.
1109     bool scrollbarsChanged = (m_object->hasAutoHorizontalScrollbar() && haveHorizontalBar != horizontalOverflow) || 
1110                              (m_object->hasAutoVerticalScrollbar() && haveVerticalBar != verticalOverflow);    
1111     if (scrollbarsChanged) {
1112         if (m_object->hasAutoHorizontalScrollbar())
1113             setHasHorizontalScrollbar(horizontalOverflow);
1114         if (m_object->hasAutoVerticalScrollbar())
1115             setHasVerticalScrollbar(verticalOverflow);
1116
1117 #if PLATFORM(MAC)
1118         // Force an update since we know the scrollbars have changed things.
1119         if (m_object->document()->hasDashboardRegions())
1120             m_object->document()->setDashboardRegionsDirty(true);
1121 #endif
1122
1123         m_object->repaint();
1124
1125         if (m_object->style()->overflowX() == OAUTO || m_object->style()->overflowY() == OAUTO) {
1126             if (!m_inOverflowRelayout) {
1127                 // Our proprietary overflow: overlay value doesn't trigger a layout.
1128                 m_inOverflowRelayout = true;
1129                 m_object->setNeedsLayout(true);
1130                 if (m_object->isRenderBlock())
1131                     static_cast<RenderBlock*>(m_object)->layoutBlock(true);
1132                 else
1133                     m_object->layout();
1134                 m_inOverflowRelayout = false;
1135             }
1136         }
1137     }
1138
1139     // Set up the range (and page step/line step).
1140     if (m_hBar) {
1141         int clientWidth = m_object->clientWidth();
1142         int pageStep = (clientWidth-PAGE_KEEP);
1143         if (pageStep < 0) pageStep = clientWidth;
1144         m_hBar->setSteps(LINE_STEP, pageStep);
1145         m_hBar->setProportion(clientWidth, m_scrollWidth);
1146         m_hBar->setValue(scrollXOffset());
1147     }
1148     if (m_vBar) {
1149         int clientHeight = m_object->clientHeight();
1150         int pageStep = (clientHeight-PAGE_KEEP);
1151         if (pageStep < 0) pageStep = clientHeight;
1152         m_vBar->setSteps(LINE_STEP, pageStep);
1153         m_vBar->setProportion(clientHeight, m_scrollHeight);
1154         m_object->repaintRectangle(IntRect(m_object->borderLeft() + m_object->clientWidth(),
1155                                    m_object->borderTop(), verticalScrollbarWidth(), 
1156                                    m_object->height() - m_object->borderTop() - m_object->borderBottom()));
1157     }
1158  
1159     if (m_object->element() && m_object->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
1160         updateOverflowStatus(horizontalOverflow, verticalOverflow);
1161 }
1162
1163 void
1164 RenderLayer::paintScrollbars(GraphicsContext* p, const IntRect& damageRect)
1165 {
1166     // Move the widgets if necessary.  We normally move and resize widgets during layout, but sometimes
1167     // widgets can move without layout occurring (most notably when you scroll a document that
1168     // contains fixed positioned elements).
1169     positionResizeControl();
1170     if (m_hBar || m_vBar) {
1171         int x = 0;
1172         int y = 0;
1173         convertToLayerCoords(root(), x, y);
1174         IntRect layerBounds = IntRect(x, y, width(), height());
1175         positionScrollbars(layerBounds);
1176     }
1177
1178     // Now that we're sure the scrollbars are in the right place, paint them.
1179     if (m_hBar)
1180         m_hBar->paint(p, damageRect);
1181     if (m_vBar)
1182         m_vBar->paint(p, damageRect);
1183 }
1184
1185 void RenderLayer::paintResizeControl(GraphicsContext* c)
1186 {
1187     if (resizeControlRect().isEmpty())
1188         return;
1189     
1190     if (!m_resizeCornerImage)
1191         m_resizeCornerImage = Image::loadPlatformResource("textAreaResizeCorner");
1192
1193     IntPoint imagePoint(resizeControlRect().right() - m_resizeCornerImage->width(), resizeControlRect().bottom() - m_resizeCornerImage->height());
1194     c->drawImage(m_resizeCornerImage, imagePoint);
1195 }
1196
1197 bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
1198 {
1199     bool didHorizontalScroll = false;
1200     bool didVerticalScroll = false;
1201     
1202     if (m_hBar) {
1203         if (granularity == ScrollByDocument) {
1204             // Special-case for the ScrollByDocument granularity. A document scroll can only be up 
1205             // or down and in both cases the horizontal bar goes all the way to the left.
1206             didHorizontalScroll = m_hBar->scroll(ScrollLeft, ScrollByDocument, multiplier);
1207         } else
1208             didHorizontalScroll = m_hBar->scroll(direction, granularity, multiplier);
1209     }
1210
1211     if (m_vBar)
1212         didVerticalScroll = m_vBar->scroll(direction, granularity, multiplier);
1213
1214     return (didHorizontalScroll || didVerticalScroll);
1215 }
1216
1217 void
1218 RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintRestriction paintRestriction, RenderObject *paintingRoot)
1219 {
1220     paintLayer(this, p, damageRect, false, paintRestriction, paintingRoot);
1221 }
1222
1223 static void setClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
1224 {
1225     // Work around bugs in focus ring clipping on Mac.
1226     p->setFocusRingClip(clipRect);
1227     if (paintDirtyRect == clipRect)
1228         return;
1229     p->save();
1230     p->clip(clipRect);
1231 }
1232
1233 static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
1234 {
1235     // Work around bugs in focus ring clipping on Mac.
1236     p->clearFocusRingClip();
1237     if (paintDirtyRect == clipRect)
1238         return;
1239     p->restore();
1240 }
1241
1242 void
1243 RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
1244                         const IntRect& paintDirtyRect, bool haveTransparency, PaintRestriction paintRestriction,
1245                         RenderObject *paintingRoot)
1246 {
1247     // Avoid painting layers when stylesheets haven't loaded.  This eliminates FOUC.
1248     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
1249     // will do a full repaint().
1250     if (renderer()->document()->didLayoutWithPendingStylesheets() && !renderer()->isRenderView() && !renderer()->isRoot())
1251         return;
1252     
1253     // Calculate the clip rects we should use.
1254     IntRect layerBounds, damageRect, clipRectToApply, outlineRect;
1255     calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
1256     int x = layerBounds.x();
1257     int y = layerBounds.y();
1258     int tx = x - renderer()->xPos();
1259     int ty = y - renderer()->yPos() + renderer()->borderTopExtra();
1260                              
1261     // Ensure our lists are up-to-date.
1262     updateZOrderLists();
1263     updateOverflowList();
1264
1265     // If this layer is totally invisible then there is nothing to paint.
1266     if (!m_object->opacity())
1267         return;
1268         
1269     bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyWhiteText;
1270     bool forceWhiteText = paintRestriction == PaintRestrictionSelectionOnlyWhiteText;
1271
1272     if (isTransparent())
1273         haveTransparency = true;
1274
1275     // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
1276     // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
1277     // Else, our renderer tree may or may not contain the painting root, so we pass that root along
1278     // so it will be tested against as we decend through the renderers.
1279     RenderObject *paintingRootForRenderer = 0;
1280     if (paintingRoot && !m_object->isDescendantOf(paintingRoot))
1281         paintingRootForRenderer = paintingRoot;
1282     
1283     // We want to paint our layer, but only if we intersect the damage rect.
1284     bool shouldPaint = intersectsDamageRect(layerBounds, damageRect);
1285     if (shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
1286         // Begin transparency layers lazily now that we know we have to paint something.
1287         if (haveTransparency)
1288             beginTransparencyLayers(p, paintDirtyRect);
1289         
1290         // Paint our background first, before painting any child layers.
1291         // Establish the clip used to paint our background.
1292         setClip(p, paintDirtyRect, damageRect);
1293
1294         // Paint the background.
1295         RenderObject::PaintInfo info(p, damageRect, PaintPhaseBlockBackground, false, paintingRootForRenderer, 0);
1296         renderer()->paint(info, tx, ty);
1297
1298         // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
1299         // z-index.  We paint after we painted the background/border, so that the scrollbars will
1300         // sit above the background/border.
1301         paintScrollbars(p, damageRect);
1302         paintResizeControl(p);
1303         // Restore the clip.
1304         restoreClip(p, paintDirtyRect, damageRect);
1305     }
1306
1307     // Now walk the sorted list of children with negative z-indices.
1308     if (m_negZOrderList)
1309         for (Vector<RenderLayer*>::iterator it = m_negZOrderList->begin(); it != m_negZOrderList->end(); ++it)
1310             it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
1311     
1312     // Now establish the appropriate clip and paint our child RenderObjects.
1313     if (shouldPaint && !clipRectToApply.isEmpty()) {
1314         // Begin transparency layers lazily now that we know we have to paint something.
1315         if (haveTransparency)
1316             beginTransparencyLayers(p, paintDirtyRect);
1317
1318         // Set up the clip used when painting our children.
1319         setClip(p, paintDirtyRect, clipRectToApply);
1320         RenderObject::PaintInfo info(p, clipRectToApply, 
1321                                      selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds,
1322                                      forceWhiteText,
1323                                      paintingRootForRenderer, 0);
1324         renderer()->paint(info, tx, ty);
1325         if (!selectionOnly) {
1326             info.phase = PaintPhaseFloat;
1327             renderer()->paint(info, tx, ty);
1328             info.phase = PaintPhaseForeground;
1329             renderer()->paint(info, tx, ty);
1330             info.phase = PaintPhaseChildOutlines;
1331             renderer()->paint(info, tx, ty);
1332         }
1333
1334         // Now restore our clip.
1335         restoreClip(p, paintDirtyRect, clipRectToApply);
1336     }
1337     
1338     if (!outlineRect.isEmpty()) {
1339         // Paint our own outline
1340         RenderObject::PaintInfo info(p, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0);
1341         setClip(p, paintDirtyRect, outlineRect);
1342         renderer()->paint(info, tx, ty);
1343         restoreClip(p, paintDirtyRect, outlineRect);
1344     }
1345     
1346     // Paint any child layers that have overflow.
1347     if (m_overflowList)
1348         for (Vector<RenderLayer*>::iterator it = m_overflowList->begin(); it != m_overflowList->end(); ++it)
1349             it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
1350     
1351     // Now walk the sorted list of children with positive z-indices.
1352     if (m_posZOrderList)
1353         for (Vector<RenderLayer*>::iterator it = m_posZOrderList->begin(); it != m_posZOrderList->end(); ++it)
1354             it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
1355     
1356     // End our transparency layer
1357     if (isTransparent() && m_usedTransparency) {
1358         p->endTransparencyLayer();
1359         p->restore();
1360         m_usedTransparency = false;
1361     }
1362 }
1363
1364 static inline bool isSubframe(RenderObject* renderer)
1365 {
1366     return renderer->isRenderView() && renderer->node()->document()->frame()->tree()->parent();
1367 }
1368
1369 static inline IntRect frameVisibleRect(RenderObject* renderer)
1370 {
1371     return enclosingIntRect(renderer->node()->document()->frame()->view()->visibleContentRect());
1372 }
1373
1374 bool
1375 RenderLayer::hitTest(RenderObject::NodeInfo& info, const IntPoint& point)
1376 {
1377     renderer()->document()->updateLayout();
1378     
1379     IntRect boundsRect(m_x, m_y, width(), height());
1380     if (isSubframe(renderer()))
1381         boundsRect.intersect(frameVisibleRect(renderer()));
1382
1383     RenderLayer* insideLayer = hitTestLayer(this, info, point, boundsRect);
1384
1385     // Now determine if the result is inside an anchor; make sure an image map wins if
1386     // it already set URLElement and only use the innermost.
1387     Node* node = info.innerNode();
1388     while (node) {
1389         if (node->isLink() && !info.URLElement())
1390             info.setURLElement(static_cast<Element*>(node));
1391         node = node->parentNode();
1392     }
1393
1394     // Next set up the correct :hover/:active state along the new chain.
1395     updateHoverActiveState(info);
1396     
1397     // Now return whether we were inside this layer (this will always be true for the root
1398     // layer).
1399     return insideLayer;
1400 }
1401
1402 static inline bool shouldApplyImplicitCapture(RenderObject* renderer, bool mouseDown)
1403 {
1404     return mouseDown && renderer->isRoot();
1405 }
1406
1407 RenderLayer*
1408 RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderObject::NodeInfo& info,
1409                           const IntPoint& mousePos, const IntRect& hitTestRect)
1410 {
1411     // Calculate the clip rects we should use.
1412     IntRect layerBounds;
1413     IntRect bgRect;
1414     IntRect fgRect;
1415     IntRect outlineRect;
1416     calculateRects(rootLayer, hitTestRect, layerBounds, bgRect, fgRect, outlineRect);
1417     
1418     // Ensure our lists are up-to-date.
1419     updateZOrderLists();
1420     updateOverflowList();
1421
1422     // This variable tracks which layer the mouse ends up being inside.  The minute we find an insideLayer,
1423     // we are done and can return it.
1424     RenderLayer* insideLayer = 0;
1425     
1426     // Begin by walking our list of positive layers from highest z-index down to the lowest
1427     // z-index.
1428     if (m_posZOrderList) {
1429         for (int i = m_posZOrderList->size() - 1; i >= 0; --i) {
1430             insideLayer = m_posZOrderList->at(i)->hitTestLayer(rootLayer, info, mousePos, hitTestRect);
1431             if (insideLayer)
1432                 return insideLayer;
1433         }
1434     }
1435
1436     // Now check our overflow objects.
1437     if (m_overflowList) {
1438         for (int i = m_overflowList->size() - 1; i >= 0; --i) {
1439             insideLayer = m_overflowList->at(i)->hitTestLayer(rootLayer, info, mousePos, hitTestRect);
1440             if (insideLayer)
1441                 return insideLayer;
1442         }
1443     }
1444
1445     // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
1446     if (fgRect.contains(mousePos) && 
1447         renderer()->hitTest(info, mousePos.x(), mousePos.y(),
1448                             layerBounds.x() - renderer()->xPos(),
1449                             layerBounds.y() - renderer()->yPos() + m_object->borderTopExtra(), HitTestDescendants)) {
1450         // for positioned generated content, we might still not have a
1451         // node by the time we get to the layer level, since none of
1452         // the content in the layer has an element. So just walk up
1453         // the tree.
1454         if (!info.innerNode()) {
1455             for (RenderObject *r = renderer(); r != NULL; r = r->parent()) { 
1456                 if (r->element()) {
1457                     info.setInnerNode(r->element());
1458                     break;
1459                 }
1460             }
1461         }
1462
1463         if (!info.innerNonSharedNode()) {
1464              for (RenderObject *r = renderer(); r != NULL; r = r->parent()) { 
1465                  if (r->element()) {
1466                      info.setInnerNonSharedNode(r->element());
1467                      break;
1468                  }
1469              }
1470         }
1471         return this;
1472     }
1473         
1474     // Now check our negative z-index children.
1475     if (m_negZOrderList) {
1476         for (int i = m_negZOrderList->size() - 1; i >= 0; --i) {
1477             insideLayer = m_negZOrderList->at(i)->hitTestLayer(rootLayer, info, mousePos, hitTestRect);
1478             if (insideLayer)
1479                 return insideLayer;
1480         }
1481     }
1482
1483     // Next we want to see if the mouse pos is inside this layer but not any of its children.
1484     // If this is the root layer and the mouse is down, we want to do this even if it doesn't
1485     // contain the point so mouse move events keep getting delivered when dragging outside the
1486     // window.
1487     if ((bgRect.contains(mousePos) || shouldApplyImplicitCapture(renderer(), info.active())) &&
1488         renderer()->hitTest(info, mousePos.x(), mousePos.y(),
1489                             layerBounds.x() - renderer()->xPos(),
1490                             layerBounds.y() - renderer()->yPos() + m_object->borderTopExtra(),
1491                             HitTestSelf))
1492         return this;
1493
1494     // No luck.
1495     return 0;
1496 }
1497
1498 void RenderLayer::calculateClipRects(const RenderLayer* rootLayer)
1499 {
1500     if (m_clipRects)
1501         return; // We have the correct cached value.
1502
1503     if (!parent()) {
1504         // The root layer's clip rect is always just its dimensions.
1505         m_clipRects = new (m_object->renderArena()) ClipRects(IntRect(0,0,width(),height()));
1506         m_clipRects->ref();
1507         return;
1508     }
1509
1510     // Ensure that our parent's clip has been calculated so that we can examine the values.
1511     parent()->calculateClipRects(rootLayer);
1512
1513     // Set up our three rects to initially match the parent rects.
1514     IntRect posClipRect(parent()->clipRects()->posClipRect());
1515     IntRect overflowClipRect(parent()->clipRects()->overflowClipRect());
1516     IntRect fixedClipRect(parent()->clipRects()->fixedClipRect());
1517
1518     // A fixed object is essentially the root of its containing block hierarchy, so when
1519     // we encounter such an object, we reset our clip rects to the fixedClipRect.
1520     if (m_object->style()->position() == FixedPosition) {
1521         posClipRect = fixedClipRect;
1522         overflowClipRect = fixedClipRect;
1523     }
1524     else if (m_object->style()->position() == RelativePosition)
1525         posClipRect = overflowClipRect;
1526     else if (m_object->style()->position() == AbsolutePosition)
1527         overflowClipRect = posClipRect;
1528     
1529     // Update the clip rects that will be passed to child layers.
1530     if (m_object->hasOverflowClip() || m_object->hasClip()) {
1531         // This layer establishes a clip of some kind.
1532         int x = 0;
1533         int y = 0;
1534         convertToLayerCoords(rootLayer, x, y);
1535         
1536         if (m_object->hasOverflowClip()) {
1537             IntRect newOverflowClip = m_object->getOverflowClipRect(x,y);
1538             overflowClipRect.intersect(newOverflowClip);
1539             if (m_object->isPositioned() || m_object->isRelPositioned())
1540                 posClipRect.intersect(newOverflowClip);
1541         }
1542         if (m_object->hasClip()) {
1543             IntRect newPosClip = m_object->getClipRect(x,y);
1544             posClipRect.intersect(newPosClip);
1545             overflowClipRect.intersect(newPosClip);
1546             fixedClipRect.intersect(newPosClip);
1547         }
1548     }
1549     
1550     // If our clip rects match our parent's clip, then we can just share its data structure and
1551     // ref count.
1552     if (posClipRect == parent()->clipRects()->posClipRect() &&
1553         overflowClipRect == parent()->clipRects()->overflowClipRect() &&
1554         fixedClipRect == parent()->clipRects()->fixedClipRect())
1555         m_clipRects = parent()->clipRects();
1556     else
1557         m_clipRects = new (m_object->renderArena()) ClipRects(overflowClipRect, fixedClipRect, posClipRect);
1558     m_clipRects->ref();
1559 }
1560
1561 void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds,
1562                                  IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect)
1563 {
1564     if (parent()) {
1565         parent()->calculateClipRects(rootLayer);
1566         backgroundRect = m_object->style()->position() == FixedPosition ? parent()->clipRects()->fixedClipRect() :
1567                          (m_object->isPositioned() ? parent()->clipRects()->posClipRect() : 
1568                                                      parent()->clipRects()->overflowClipRect());
1569         backgroundRect.intersect(paintDirtyRect);
1570     } else
1571         backgroundRect = paintDirtyRect;
1572     foregroundRect = backgroundRect;
1573     outlineRect = backgroundRect;
1574     
1575     int x = 0;
1576     int y = 0;
1577     convertToLayerCoords(rootLayer, x, y);
1578     layerBounds = IntRect(x,y,width(),height());
1579     
1580     // Update the clip rects that will be passed to child layers.
1581     if (m_object->hasOverflowClip() || m_object->hasClip()) {
1582         // This layer establishes a clip of some kind.
1583         if (m_object->hasOverflowClip())
1584             foregroundRect.intersect(m_object->getOverflowClipRect(x,y));
1585         if (m_object->hasClip()) {
1586             // Clip applies to *us* as well, so go ahead and update the damageRect.
1587             IntRect newPosClip = m_object->getClipRect(x,y);
1588             backgroundRect.intersect(newPosClip);
1589             foregroundRect.intersect(newPosClip);
1590             outlineRect.intersect(newPosClip);
1591         }
1592
1593         // If we establish a clip at all, then go ahead and make sure our background
1594         // rect is intersected with our layer's bounds.
1595         backgroundRect.intersect(layerBounds);
1596     }
1597 }
1598
1599 bool RenderLayer::intersectsDamageRect(const IntRect& layerBounds, const IntRect& damageRect) const
1600 {
1601     // Always examine the canvas and the root.
1602     if (renderer()->isRenderView() || renderer()->isRoot())
1603         return true;
1604
1605     // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we 
1606     // can go ahead and return true.
1607     if (!renderer()->isInlineFlow()) {
1608         IntRect b = layerBounds;
1609         b.inflate(renderer()->view()->maximalOutlineSize());
1610         if (b.intersects(damageRect))
1611             return true;
1612     }
1613         
1614     // Otherwise we need to compute the bounding box of this single layer and see if it intersects
1615     // the damage rect.
1616     return absoluteBoundingBox().intersects(damageRect);
1617 }
1618
1619 IntRect RenderLayer::absoluteBoundingBox() const
1620 {
1621     // There are three special cases we need to consider.
1622     // (1) Inline Flows.  For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
1623     // inline.  In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the root
1624     // line boxes of all three lines (including overflow on those lines).
1625     // (2) Left/Top Overflow.  The width/height of layers already includes right/bottom overflow.  However, in the case of left/top
1626     // overflow, we have to create a bounding box that will extend to include this overflow.
1627     // (3) Floats.  When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats
1628     // as part of our bounding box.  We do this because we are the responsible layer for both hit testing and painting those
1629     // floats.
1630     IntRect result;
1631     if (renderer()->isInlineFlow()) {
1632         // Go from our first line box to our last line box.
1633         RenderInline* inlineFlow = static_cast<RenderInline*>(renderer());
1634         InlineFlowBox* firstBox = inlineFlow->firstLineBox();
1635         if (!firstBox)
1636             return result;
1637         int top = firstBox->root()->topOverflow();
1638         int bottom = inlineFlow->lastLineBox()->root()->bottomOverflow();
1639         int left = firstBox->xPos();
1640         for (InlineRunBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
1641             left = min(left, curr->xPos());
1642         result = IntRect(m_x + left, m_y + (top - renderer()->yPos()), width(), bottom - top);
1643     } else if (renderer()->isTableRow()) {
1644         // Our bounding box is just the union of all of our cells' border/overflow rects.
1645         for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
1646             if (child->isTableCell()) {
1647                 IntRect bbox = child->borderBox();
1648                 bbox.move(0, child->borderTopExtra());
1649                 result.unite(bbox);
1650                 IntRect overflowRect = renderer()->overflowRect(false);
1651                 overflowRect.move(0, child->borderTopExtra());
1652                 if (bbox != overflowRect)
1653                     result.unite(overflowRect);
1654             }
1655         }
1656         result.move(m_x, m_y);
1657     } else {
1658         IntRect bbox = renderer()->borderBox();
1659         result = bbox;
1660         IntRect overflowRect = renderer()->overflowRect(false);
1661         if (bbox != overflowRect)
1662             result.unite(overflowRect);
1663         IntRect floatRect = renderer()->floatRect();
1664         if (bbox != floatRect)
1665             result.unite(floatRect);
1666         
1667         // We have to adjust the x/y of this result so that it is in the coordinate space of the layer.
1668         // We also have to add in borderTopExtra here, since borderBox(), in order to play well with methods like
1669         // floatRect that deal with child content, uses an origin of (0,0) that is at the child content box (so
1670         // border box returns a y coord of -borderTopExtra().  The layer, however, uses the outer box.  This is all
1671         // really confusing.
1672         result.move(m_x, m_y + renderer()->borderTopExtra());
1673     }
1674     
1675     // Convert the bounding box to an absolute position.  We can do this easily by looking at the delta
1676     // between the bounding box's xpos and our layer's xpos and then applying that to the absolute layerBounds
1677     // passed in.
1678     int absX = 0, absY = 0;
1679     convertToLayerCoords(root(), absX, absY);
1680     result.move(absX - m_x, absY - m_y);
1681     result.inflate(renderer()->view()->maximalOutlineSize());
1682     return result;
1683 }
1684
1685 void RenderLayer::clearClipRects()
1686 {
1687     if (!m_clipRects)
1688         return;
1689
1690     clearClipRect();
1691     
1692     for (RenderLayer* l = firstChild(); l; l = l->nextSibling())
1693         l->clearClipRects();
1694 }
1695
1696 void RenderLayer::clearClipRect()
1697 {
1698     if (m_clipRects) {
1699         m_clipRects->deref(m_object->renderArena());
1700         m_clipRects = 0;
1701     }
1702 }
1703
1704 static RenderObject* commonAncestor(RenderObject* obj1, RenderObject* obj2)
1705 {
1706     if (!obj1 || !obj2)
1707         return 0;
1708
1709     for (RenderObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor())
1710         for (RenderObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor())
1711             if (currObj1 == currObj2)
1712                 return currObj1;
1713
1714     return 0;
1715 }
1716
1717 void RenderLayer::updateHoverActiveState(RenderObject::NodeInfo& info)
1718 {
1719     // We don't update :hover/:active state when the info is marked as readonly.
1720     if (info.readonly())
1721         return;
1722
1723     Document* doc = renderer()->document();
1724     if (!doc) return;
1725
1726     Node* activeNode = doc->activeNode();
1727     if (activeNode && !info.active()) {
1728         // We are clearing the :active chain because the mouse has been released.
1729         for (RenderObject* curr = activeNode->renderer(); curr; curr = curr->parent()) {
1730             if (curr->element() && !curr->isText())
1731                 curr->element()->setInActiveChain(false);
1732         }
1733         doc->setActiveNode(0);
1734     } else {
1735         Node* newActiveNode = info.innerNode();
1736         if (!activeNode && newActiveNode && info.active()) {
1737             // We are setting the :active chain and freezing it. If future moves happen, they
1738             // will need to reference this chain.
1739             for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) {
1740                 if (curr->element() && !curr->isText()) {
1741                     curr->element()->setInActiveChain(true);
1742                 }
1743             }
1744             doc->setActiveNode(newActiveNode);
1745         }
1746     }
1747
1748     // If the mouse is down and if this is a mouse move event, we want to restrict changes in 
1749     // :hover/:active to only apply to elements that are in the :active chain that we froze
1750     // at the time the mouse went down.
1751     bool mustBeInActiveChain = info.active() && info.mouseMove();
1752
1753     // Check to see if the hovered node has changed.  If not, then we don't need to
1754     // do anything.  
1755     Node* oldHoverNode = doc->hoverNode();
1756     Node* newHoverNode = info.innerNode();
1757
1758     // Update our current hover node.
1759     doc->setHoverNode(newHoverNode);
1760
1761     // We have two different objects.  Fetch their renderers.
1762     RenderObject* oldHoverObj = oldHoverNode ? oldHoverNode->renderer() : 0;
1763     RenderObject* newHoverObj = newHoverNode ? newHoverNode->renderer() : 0;
1764     
1765     // Locate the common ancestor render object for the two renderers.
1766     RenderObject* ancestor = commonAncestor(oldHoverObj, newHoverObj);
1767
1768     if (oldHoverObj != newHoverObj) {
1769         // The old hover path only needs to be cleared up to (and not including) the common ancestor;
1770         for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
1771             if (curr->element() && !curr->isText() && (!mustBeInActiveChain || curr->element()->inActiveChain())) {
1772                 curr->element()->setActive(false);
1773                 curr->element()->setHovered(false);
1774             }
1775         }
1776     }
1777
1778     // Now set the hover state for our new object up to the root.
1779     for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) {
1780         if (curr->element() && !curr->isText() && (!mustBeInActiveChain || curr->element()->inActiveChain())) {
1781             curr->element()->setActive(info.active());
1782             curr->element()->setHovered(true);
1783         }
1784     }
1785 }
1786
1787 // Helper for the sorting of layers by z-index.
1788 static inline bool compareZIndex(RenderLayer* first, RenderLayer* second)
1789 {
1790     return first->zIndex() < second->zIndex();
1791 }
1792
1793 void RenderLayer::dirtyZOrderLists()
1794 {
1795     if (m_posZOrderList)
1796         m_posZOrderList->clear();
1797     if (m_negZOrderList)
1798         m_negZOrderList->clear();
1799     m_zOrderListsDirty = true;
1800 }
1801
1802 void RenderLayer::dirtyOverflowList()
1803 {
1804     if (m_overflowList)
1805         m_overflowList->clear();
1806     m_overflowListDirty = true;
1807 }
1808
1809 void RenderLayer::updateZOrderLists()
1810 {
1811     if (!isStackingContext() || !m_zOrderListsDirty)
1812         return;
1813     
1814     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
1815         child->collectLayers(m_posZOrderList, m_negZOrderList);
1816
1817     // Sort the two lists.
1818     if (m_posZOrderList)
1819         std::stable_sort(m_posZOrderList->begin(), m_posZOrderList->end(), compareZIndex);
1820     if (m_negZOrderList)
1821         std::stable_sort(m_negZOrderList->begin(), m_negZOrderList->end(), compareZIndex);
1822
1823     m_zOrderListsDirty = false;
1824 }
1825
1826 void RenderLayer::updateOverflowList()
1827 {
1828     if (!m_overflowListDirty)
1829         return;
1830         
1831     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1832         if (child->isOverflowOnly()) {
1833             if (!m_overflowList)
1834                 m_overflowList = new Vector<RenderLayer*>;
1835             m_overflowList->append(child);
1836         }
1837     }
1838     
1839     m_overflowListDirty = false;
1840 }
1841
1842 void RenderLayer::collectLayers(Vector<RenderLayer*>*& posBuffer, Vector<RenderLayer*>*& negBuffer)
1843 {
1844     // FIXME: A child render object or layer could override visibility.  Don't remove this
1845     // optimization though until RenderObject's nodeAtPoint is patched to understand what to do
1846     // when visibility is overridden by a child.
1847     if (renderer()->style()->visibility() != VISIBLE)
1848         return;
1849
1850     // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
1851     if (!isOverflowOnly()) {
1852         // Determine which buffer the child should be in.
1853         Vector<RenderLayer*>*& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
1854
1855         // Create the buffer if it doesn't exist yet.
1856         if (!buffer)
1857             buffer = new Vector<RenderLayer*>;
1858         
1859         // Append ourselves at the end of the appropriate buffer.
1860         buffer->append(this);
1861     }
1862
1863     // Recur into our children to collect more layers, but only if we don't establish
1864     // a stacking context.
1865     if (!isStackingContext())
1866         for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
1867             child->collectLayers(posBuffer, negBuffer);
1868 }
1869
1870 void RenderLayer::repaintIncludingDescendants()
1871 {
1872     m_object->repaint();
1873     for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
1874         curr->repaintIncludingDescendants();
1875 }
1876
1877 bool RenderLayer::shouldBeOverflowOnly() const
1878 {
1879     return renderer()->hasOverflowClip() && 
1880            !renderer()->isPositioned() &&
1881            !renderer()->isRelPositioned() &&
1882            !isTransparent();
1883 }
1884
1885 void RenderLayer::styleChanged()
1886 {
1887     bool isOverflowOnly = shouldBeOverflowOnly();
1888     if (isOverflowOnly != m_isOverflowOnly) {
1889         m_isOverflowOnly = isOverflowOnly;
1890         RenderLayer* p = parent();
1891         RenderLayer* sc = stackingContext();
1892         if (p)
1893             p->dirtyOverflowList();
1894         if (sc)
1895             sc->dirtyZOrderLists();
1896     }
1897
1898     if (m_object->style()->overflowX() == OMARQUEE && m_object->style()->marqueeBehavior() != MNONE) {
1899         if (!m_marquee)
1900             m_marquee = new Marquee(this);
1901         m_marquee->updateMarqueeStyle();
1902     }
1903     else if (m_marquee) {
1904         delete m_marquee;
1905         m_marquee = 0;
1906     }
1907 }
1908
1909 void RenderLayer::suspendMarquees()
1910 {
1911     if (m_marquee)
1912         m_marquee->suspend();
1913     
1914     for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
1915         curr->suspendMarquees();
1916 }
1917
1918 // --------------------------------------------------------------------------
1919 // Marquee implementation
1920
1921 Marquee::Marquee(RenderLayer* l)
1922     : m_layer(l), m_currentLoop(0)
1923     , m_timer(this, &Marquee::timerFired)
1924     , m_start(0), m_end(0), m_speed(0), m_unfurlPos(0), m_reset(false)
1925     , m_suspended(false), m_stopped(false), m_whiteSpace(NORMAL), m_direction(MAUTO)
1926 {
1927 }
1928
1929 int Marquee::marqueeSpeed() const
1930 {
1931     int result = m_layer->renderer()->style()->marqueeSpeed();
1932     Node* elt = m_layer->renderer()->element();
1933     if (elt && elt->hasTagName(marqueeTag)) {
1934         HTMLMarqueeElement* marqueeElt = static_cast<HTMLMarqueeElement*>(elt);
1935         result = max(result, marqueeElt->minimumDelay());
1936     }
1937     return result;
1938 }
1939
1940 EMarqueeDirection Marquee::direction() const
1941 {
1942     // FIXME: Support the CSS3 "auto" value for determining the direction of the marquee.
1943     // For now just map MAUTO to MBACKWARD
1944     EMarqueeDirection result = m_layer->renderer()->style()->marqueeDirection();
1945     TextDirection dir = m_layer->renderer()->style()->direction();
1946     if (result == MAUTO)
1947         result = MBACKWARD;
1948     if (result == MFORWARD)
1949         result = (dir == LTR) ? MRIGHT : MLEFT;
1950     if (result == MBACKWARD)
1951         result = (dir == LTR) ? MLEFT : MRIGHT;
1952     
1953     // Now we have the real direction.  Next we check to see if the increment is negative.
1954     // If so, then we reverse the direction.
1955     Length increment = m_layer->renderer()->style()->marqueeIncrement();
1956     if (increment.value() < 0)
1957         result = static_cast<EMarqueeDirection>(-result);
1958     
1959     return result;
1960 }
1961
1962 bool Marquee::isHorizontal() const
1963 {
1964     return direction() == MLEFT || direction() == MRIGHT;
1965 }
1966
1967 bool Marquee::isUnfurlMarquee() const
1968 {
1969     EMarqueeBehavior behavior = m_layer->renderer()->style()->marqueeBehavior();
1970     return (behavior == MUNFURL);
1971 }
1972
1973 int Marquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge)
1974 {
1975     RenderObject* o = m_layer->renderer();
1976     RenderStyle* s = o->style();
1977     if (isHorizontal()) {
1978         bool ltr = s->direction() == LTR;
1979         int clientWidth = o->clientWidth();
1980         int contentWidth = ltr ? o->rightmostPosition(true, false) : o->leftmostPosition(true, false);
1981         if (ltr)
1982             contentWidth += (o->paddingRight() - o->borderLeft());
1983         else {
1984             contentWidth = o->width() - contentWidth;
1985             contentWidth += (o->paddingLeft() - o->borderRight());
1986         }
1987         if (dir == MRIGHT) {
1988             if (stopAtContentEdge)
1989                 return max(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));
1990             else
1991                 return ltr ? contentWidth : clientWidth;
1992         }
1993         else {
1994             if (stopAtContentEdge)
1995                 return min(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));
1996             else
1997                 return ltr ? -clientWidth : -contentWidth;
1998         }
1999     }
2000     else {
2001         int contentHeight = m_layer->renderer()->lowestPosition(true, false) - 
2002                             m_layer->renderer()->borderTop() + m_layer->renderer()->paddingBottom();
2003         int clientHeight = m_layer->renderer()->clientHeight();
2004         if (dir == MUP) {
2005             if (stopAtContentEdge)
2006                  return min(contentHeight - clientHeight, 0);
2007             else
2008                 return -clientHeight;
2009         }
2010         else {
2011             if (stopAtContentEdge)
2012                 return max(contentHeight - clientHeight, 0);
2013             else 
2014                 return contentHeight;
2015         }
2016     }    
2017 }
2018
2019 void Marquee::start()
2020 {
2021     if (m_timer.isActive() || m_layer->renderer()->style()->marqueeIncrement().value() == 0)
2022         return;
2023     
2024     if (!m_suspended && !m_stopped) {
2025         if (isUnfurlMarquee()) {
2026             bool forward = direction() == MDOWN || direction() == MRIGHT;
2027             bool isReversed = (forward && m_currentLoop % 2) || (!forward && !(m_currentLoop % 2));
2028             m_unfurlPos = isReversed ? m_end : m_start;
2029             m_layer->renderer()->setChildNeedsLayout(true);
2030         }
2031         else {
2032             if (isHorizontal())
2033                 m_layer->scrollToOffset(m_start, 0, false, false);
2034             else
2035                 m_layer->scrollToOffset(0, m_start, false, false);
2036         }
2037         // FIXME: At this point a scroll event fired, which could have deleted this layer,
2038         // including the marquee. Need to handle this case.
2039     }
2040     else {
2041         m_suspended = false;
2042         m_stopped = false;
2043     }
2044
2045     m_timer.startRepeating(speed() * 0.001);
2046 }
2047
2048 void Marquee::suspend()
2049 {
2050     m_timer.stop();
2051     m_suspended = true;
2052 }
2053
2054 void Marquee::stop()
2055 {
2056     m_timer.stop();
2057     m_stopped = true;
2058 }
2059
2060 void Marquee::updateMarqueePosition()
2061 {
2062     bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops);
2063     if (activate) {
2064         if (isUnfurlMarquee()) {
2065             if (m_unfurlPos < m_start) {
2066                 m_unfurlPos = m_start;
2067                 m_layer->renderer()->setChildNeedsLayout(true);
2068             }
2069             else if (m_unfurlPos > m_end) {
2070                 m_unfurlPos = m_end;
2071                 m_layer->renderer()->setChildNeedsLayout(true);
2072             }
2073         }
2074         else {
2075             EMarqueeBehavior behavior = m_layer->renderer()->style()->marqueeBehavior();
2076             m_start = computePosition(direction(), behavior == MALTERNATE);
2077             m_end = computePosition(reverseDirection(), behavior == MALTERNATE || behavior == MSLIDE);
2078         }
2079         if (!m_stopped)
2080             start();
2081     }
2082 }
2083
2084 void Marquee::updateMarqueeStyle()
2085 {
2086     RenderStyle* s = m_layer->renderer()->style();
2087     
2088     if (m_direction != s->marqueeDirection() || (m_totalLoops != s->marqueeLoopCount() && m_currentLoop >= m_totalLoops))
2089         m_currentLoop = 0; // When direction changes or our loopCount is a smaller number than our current loop, reset our loop.
2090     
2091     m_totalLoops = s->marqueeLoopCount();
2092     m_direction = s->marqueeDirection();
2093     m_whiteSpace = s->whiteSpace();
2094     
2095     if (m_layer->renderer()->isHTMLMarquee()) {
2096         // Hack for WinIE.  In WinIE, a value of 0 or lower for the loop count for SLIDE means to only do
2097         // one loop.
2098         if (m_totalLoops <= 0 && (s->marqueeBehavior() == MSLIDE || s->marqueeBehavior() == MUNFURL))
2099             m_totalLoops = 1;
2100         
2101         // Hack alert: Set the white-space value to nowrap for horizontal marquees with inline children, thus ensuring
2102         // all the text ends up on one line by default.  Limit this hack to the <marquee> element to emulate
2103         // WinIE's behavior.  Someone using CSS3 can use white-space: nowrap on their own to get this effect.
2104         // Second hack alert: Set the text-align back to auto.  WinIE completely ignores text-align on the
2105         // marquee element.
2106         // FIXME: Bring these up with the CSS WG.
2107         if (isHorizontal() && m_layer->renderer()->childrenInline()) {
2108             s->setWhiteSpace(NOWRAP);
2109             s->setTextAlign(TAAUTO);
2110         }
2111     }
2112     
2113     // Marquee height hack!! Make sure that, if it is a horizontal marquee, the height attribute is overridden 
2114     // if it is smaller than the font size. If it is a vertical marquee and height is not specified, we default
2115     // to a marquee of 200px.
2116     if (isHorizontal()) {
2117         if (s->height().isFixed() && s->height().value() < s->fontSize())
2118             s->setHeight(Length(s->fontSize(),Fixed));
2119     } else if (s->height().isAuto())  //vertical marquee with no specified height
2120         s->setHeight(Length(200, Fixed)); 
2121    
2122     if (speed() != marqueeSpeed()) {
2123         m_speed = marqueeSpeed();
2124         if (m_timer.isActive())
2125             m_timer.startRepeating(speed() * 0.001);
2126     }
2127     
2128     // Check the loop count to see if we should now stop.
2129     bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops);
2130     if (activate && !m_timer.isActive())
2131         m_layer->renderer()->setNeedsLayout(true);
2132     else if (!activate && m_timer.isActive())
2133         m_timer.stop();
2134 }
2135
2136 void Marquee::timerFired(Timer<Marquee>*)
2137 {
2138     if (m_layer->renderer()->needsLayout())
2139         return;
2140     
2141     if (m_reset) {
2142         m_reset = false;
2143         if (isHorizontal())
2144             m_layer->scrollToXOffset(m_start);
2145         else
2146             m_layer->scrollToYOffset(m_start);
2147         return;
2148     }
2149     
2150     RenderStyle* s = m_layer->renderer()->style();
2151     
2152     int endPoint = m_end;
2153     int range = m_end - m_start;
2154     int newPos;
2155     if (range == 0)
2156         newPos = m_end;
2157     else {  
2158         bool addIncrement = direction() == MUP || direction() == MLEFT;
2159         bool isReversed = s->marqueeBehavior() == MALTERNATE && m_currentLoop % 2;
2160         if (isUnfurlMarquee()) {
2161             isReversed = (!addIncrement && m_currentLoop % 2) || (addIncrement && !(m_currentLoop % 2));
2162             addIncrement = !isReversed;
2163         }
2164         if (isReversed) {
2165             // We're going in the reverse direction.
2166             endPoint = m_start;
2167             range = -range;
2168             if (!isUnfurlMarquee())
2169                 addIncrement = !addIncrement;
2170         }
2171         bool positive = range > 0;
2172         int clientSize = isUnfurlMarquee() ? abs(range) :
2173             (isHorizontal() ? m_layer->renderer()->clientWidth() : m_layer->renderer()->clientHeight());
2174         int increment = max(1, abs(m_layer->renderer()->style()->marqueeIncrement().calcValue(clientSize)));
2175         int currentPos = isUnfurlMarquee() ? m_unfurlPos : 
2176             (isHorizontal() ? m_layer->scrollXOffset() : m_layer->scrollYOffset());
2177         newPos =  currentPos + (addIncrement ? increment : -increment);
2178         if (positive)
2179             newPos = min(newPos, endPoint);
2180         else
2181             newPos = max(newPos, endPoint);
2182     }
2183
2184     if (newPos == endPoint) {
2185         m_currentLoop++;
2186         if (m_totalLoops > 0 && m_currentLoop >= m_totalLoops)
2187             m_timer.stop();
2188         else if (s->marqueeBehavior() != MALTERNATE && s->marqueeBehavior() != MUNFURL)
2189             m_reset = true;
2190     }
2191     
2192     if (isUnfurlMarquee()) {
2193         m_unfurlPos = newPos;
2194         m_layer->renderer()->setChildNeedsLayout(true);
2195     }
2196     else {
2197         if (isHorizontal())
2198             m_layer->scrollToXOffset(newPos);
2199         else
2200             m_layer->scrollToYOffset(newPos);
2201     }
2202 }
2203
2204 }