2011-02-01  Darin Adler  <darin@apple.com>

        Reviewed by Chris Fleizach.

        REGRESSION: Removing focus from area element causes unwanted scrolling
        https://bugs.webkit.org/show_bug.cgi?id=50169

        Test: fast/images/imagemap-scroll.html

        * html/HTMLAreaElement.cpp:
        (WebCore::HTMLAreaElement::setFocus): Added override. Calls the new
        RenderImage::areaElementFocusChanged function.
        (WebCore::HTMLAreaElement::updateFocusAppearance): Removed the code
        here that calls setNeedsLayout on the image's renderer. This was an
        attempt to cause repaint of the renderer, but this function does not
        need to do that. Also changed this to use the imageElement function
        to avoid repeating code.

        * html/HTMLAreaElement.h: Updated for above changes.

        * rendering/RenderImage.cpp:
        (WebCore::RenderImage::paint): Updated for name change.
        (WebCore::RenderImage::paintAreaElementFocusRing): Renamed this from
        paintFocusRing, because it only paints area focus rings, and should
        not be confused with paintFocusRing functions in other classes. Also
        removed the unused style argument. Removed the code that used an
        HTMLCollection to see if the focused area element is for this image
        and instead just call imageElement on the area element.
        (WebCore::RenderImage::areaElementFocusChanged): Added. Calls repaint.

        * rendering/RenderImage.h: Added a public areaElementFocusChanged
        function for HTMLAreaElement to call. Made the paintFocusRing function
        private, renamed it to paintAreaElementFocusRing, and removed its
        unused style argument.
2011-02-01  Darin Adler  <darin@apple.com>

        Reviewed by Chris Fleizach.

        REGRESSION: Removing focus from area element causes unwanted scrolling
        https://bugs.webkit.org/show_bug.cgi?id=50169

        * fast/images/imagemap-scroll-expected.txt: Added.
        * fast/images/imagemap-scroll.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@77313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index 41c8d76..cb5828e 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -4,7 +4,7 @@
  *           (C) 2000 Dirk Mueller (mueller@kde.org)
  *           (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com)
  *           (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
  * Copyright (C) 2010 Google Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -30,7 +30,6 @@
 #include "Frame.h"
 #include "GraphicsContext.h"
 #include "HTMLAreaElement.h"
-#include "HTMLCollection.h"
 #include "HTMLImageElement.h"
 #include "HTMLInputElement.h"
 #include "HTMLMapElement.h"
@@ -38,11 +37,9 @@
 #include "HitTestResult.h"
 #include "Page.h"
 #include "RenderLayer.h"
-#include "RenderTheme.h"
 #include "RenderView.h"
 #include "SelectionController.h"
 #include "TextRun.h"
-#include <wtf/CurrentTime.h>
 #include <wtf/UnusedParam.h>
 
 #if ENABLE(WML)
@@ -324,47 +321,51 @@
     RenderReplaced::paint(paintInfo, tx, ty);
     
     if (paintInfo.phase == PaintPhaseOutline)
-        paintFocusRing(paintInfo, style());
+        paintAreaElementFocusRing(paintInfo);
 }
     
-void RenderImage::paintFocusRing(PaintInfo& paintInfo, const RenderStyle*)
+void RenderImage::paintAreaElementFocusRing(PaintInfo& paintInfo)
 {
-    // Don't draw focus rings if printing.
-    if (document()->printing() || !frame()->selection()->isFocusedAndActive())
+    Document* document = this->document();
+    
+    if (document->printing() || !document->frame()->selection()->isFocusedAndActive())
         return;
     
     if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
         return;
 
-    HTMLMapElement* mapElement = imageMap();
-    if (!mapElement)
-        return;
-    
-    Document* document = mapElement->document();
-    if (!document)
-        return;
-    
     Node* focusedNode = document->focusedNode();
-    if (!focusedNode)
+    if (!focusedNode || !focusedNode->hasTagName(areaTag))
         return;
-    
-    RefPtr<HTMLCollection> areas = mapElement->areas();
-    unsigned numAreas = areas->length();
-    
-    // FIXME: Clip the paths to the image bounding box.
-    for (unsigned k = 0; k < numAreas; ++k) {
-        HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(areas->item(k));
-        if (focusedNode != areaElement)
-            continue;
 
-        RenderStyle* styleToUse = areaElement->computedStyle();
-        if (theme()->supportsFocusRing(styleToUse))
-            return; // The theme draws the focus ring.
-        paintInfo.context->drawFocusRing(areaElement->getPath(this), styleToUse->outlineWidth(), styleToUse->outlineOffset(), styleToUse->visitedDependentColor(CSSPropertyOutlineColor));
-        break;
-    }
+    HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(focusedNode);
+    if (areaElement->imageElement() != node())
+        return;
+
+    // Even if the theme handles focus ring drawing for entire elements, it won't do it for
+    // an area within an image, so we don't call RenderTheme::supportsFocusRing here.
+
+    Path path = areaElement->getPath(this);
+    if (path.isEmpty())
+        return;
+
+    // FIXME: Do we need additional code to clip the path to the image's bounding box?
+
+    RenderStyle* areaElementStyle = areaElement->computedStyle();
+    paintInfo.context->drawFocusRing(path, areaElementStyle->outlineWidth(), areaElementStyle->outlineOffset(),
+        areaElementStyle->visitedDependentColor(CSSPropertyOutlineColor));
 }
-    
+
+void RenderImage::areaElementFocusChanged(HTMLAreaElement* element)
+{
+    ASSERT_UNUSED(element, element->imageElement() == node());
+
+    // It would be more efficient to only repaint the focus ring rectangle
+    // for the passed-in area element. That would require adding functions
+    // to the area element class.
+    repaint();
+}
+
 void RenderImage::paintIntoRect(GraphicsContext* context, const IntRect& rect)
 {
     if (!m_imageResource->hasImage() || m_imageResource->errorOccurred() || rect.width() <= 0 || rect.height() <= 0)