2006-06-24 Mitz Pettel <opendarwin.org@mitzpettel.com>
authorap <ap@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 24 Jun 2006 16:02:10 +0000 (16:02 +0000)
committerap <ap@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 24 Jun 2006 16:02:10 +0000 (16:02 +0000)
        Reviewed by Darin, landed by ap.

        - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=9547
          Resize corner does not track the mouse accurately

        Test: fast/css/resize-corner-tracking.html

        * page/FrameView.cpp:
        (WebCore::FrameView::handleMousePressEvent): Store the offset from the layer's
        resizing corner where dragging has started.
        (WebCore::FrameView::handleMouseMoveEvent): Pass the stored offset to the
        layer's resize method.
        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::resize): Added an offset parameter, which is added to
        the mouse location.
        For objects that may have intrinsic margins applied to them,
        added code to lift the margins into the object's style in order to keep them
        constant.
        Changed to take the content size as the base size if the box-sizing property
        is content-box.
        (WebCore::RenderLayer::offsetFromResizeCorner): Added. Returns the offset of the
        given point from the corner that tracks the mouse when resizing.
        * rendering/RenderLayer.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@15014 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/css/resize-corner-tracking-expected.checksum [new file with mode: 0644]
LayoutTests/fast/css/resize-corner-tracking-expected.png [new file with mode: 0644]
LayoutTests/fast/css/resize-corner-tracking-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/resize-corner-tracking.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/page/FrameView.cpp
WebCore/rendering/RenderLayer.cpp
WebCore/rendering/RenderLayer.h

index 8fe8bf803ab0bb9b8ad52f60527fa88b797a1d47..a7048bb3da6c243dffab616118cf14e70f7a266e 100644 (file)
@@ -1,3 +1,15 @@
+2006-06-24  Mitz Pettel  <opendarwin.org@mitzpettel.com>
+
+        Reviewed by Darin, landed by ap.
+
+        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=9547
+          Resize corner does not track the mouse accurately
+
+        * fast/css/resize-corner-tracking-expected.checksum: Added.
+        * fast/css/resize-corner-tracking-expected.png: Added.
+        * fast/css/resize-corner-tracking-expected.txt: Added.
+        * fast/css/resize-corner-tracking.html: Added.
+
 2006-06-24  Mitz Pettel  <opendarwin.org@mitzpettel.com>
 
         Reviewed by Darin. landed by ap.
diff --git a/LayoutTests/fast/css/resize-corner-tracking-expected.checksum b/LayoutTests/fast/css/resize-corner-tracking-expected.checksum
new file mode 100644 (file)
index 0000000..295b47c
--- /dev/null
@@ -0,0 +1,2 @@
+a632ad30744dd97d7caa8bbb49d116e8
+\ No newline at end of file
diff --git a/LayoutTests/fast/css/resize-corner-tracking-expected.png b/LayoutTests/fast/css/resize-corner-tracking-expected.png
new file mode 100644 (file)
index 0000000..1333c49
Binary files /dev/null and b/LayoutTests/fast/css/resize-corner-tracking-expected.png differ
diff --git a/LayoutTests/fast/css/resize-corner-tracking-expected.txt b/LayoutTests/fast/css/resize-corner-tracking-expected.txt
new file mode 100644 (file)
index 0000000..f5a3031
--- /dev/null
@@ -0,0 +1,33 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {HR} at (0,0) size 784x2 [border: (1px inset #000000)]
+      RenderBlock {P} at (0,18) size 784x18
+        RenderText {#text} at (0,0) size 53x18
+          text run at (0,0) width 53: "Test for "
+        RenderInline {I} at (0,0) size 669x18
+          RenderInline {A} at (0,0) size 348x18 [color=#0000EE]
+            RenderText {#text} at (53,0) size 348x18
+              text run at (53,0) width 348: "http://bugzilla.opendarwin.org/show_bug.cgi?id=9547"
+          RenderText {#text} at (401,0) size 321x18
+            text run at (401,0) width 4: " "
+            text run at (405,0) width 317: "Resize corner does not track the mouse accurately"
+        RenderText {#text} at (722,0) size 4x18
+          text run at (722,0) width 4: "."
+      RenderBlock {HR} at (0,52) size 784x2 [border: (1px inset #000000)]
+      RenderBlock (anonymous) at (0,187) size 784x178
+        RenderTextField {TEXTAREA} at (0,0) size 169x121 [bgcolor=#FFFFFF] [border: (2px solid #0000FF)]
+        RenderText {#text} at (169,107) size 4x18
+          text run at (169,107) width 4: " "
+        RenderBR {BR} at (0,0) size 0x0
+        RenderTextField {TEXTAREA} at (2,127) size 182x49 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+layer at (8,70) size 173x125 clip at (10,72) size 169x121
+  RenderBlock {DIV} at (0,62) size 173x125 [border: (2px solid #0000FF)]
+layer at (10,197) size 165x117
+  RenderBlock {DIV} at (2,2) size 165x117
+layer at (11,323) size 180x47
+  RenderBlock {DIV} at (1,1) size 180x47
diff --git a/LayoutTests/fast/css/resize-corner-tracking.html b/LayoutTests/fast/css/resize-corner-tracking.html
new file mode 100644 (file)
index 0000000..bcb0f01
--- /dev/null
@@ -0,0 +1,37 @@
+<html>
+<head>
+    <title></title>
+    <script type="text/javascript">
+        function resize(id)
+        {
+            var target = document.getElementById(id);
+            var x = document.body.offsetLeft + target.offsetLeft + target.offsetWidth;
+            var y = document.body.offsetTop + target.offsetTop + target.offsetHeight;
+            eventSender.mouseMoveTo(x - 6, y - 7);
+            eventSender.mouseDown();
+            eventSender.mouseMoveTo(x + 13, y + 14);
+            eventSender.mouseUp();
+        }
+        function test()
+        {
+            if (!window.layoutTestController)
+                return;
+            resize("div");
+            resize("textarea1");
+            resize("textarea2");
+        }
+    </script>
+</head>
+<body onload="test()">
+    <hr>
+    <p>
+        Test for
+        <i><a href="http://bugzilla.opendarwin.org/show_bug.cgi?id=9547">http://bugzilla.opendarwin.org/show_bug.cgi?id=9547</a>
+        Resize corner does not track the mouse accurately</i>.
+    </p>
+    <hr>
+    <div id="div" style="overflow: auto; resize: both; width: 150px; height: 100px; border: blue 2px solid;"></div>
+    <textarea id="textarea1" style="width: 150px; height: 100px; border: blue 2px solid;"></textarea>
+    <br>
+    <textarea id="textarea2"></textarea>
+</body>
index 83bc169ea9131bb6a89aee16c62a69a1af2443ce..53ffbc45f7b5b427867b225aa78fcce3e478e7f7 100644 (file)
@@ -1,3 +1,29 @@
+2006-06-24  Mitz Pettel  <opendarwin.org@mitzpettel.com>
+
+        Reviewed by Darin, landed by ap.
+
+        - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=9547
+          Resize corner does not track the mouse accurately
+
+        Test: fast/css/resize-corner-tracking.html
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::handleMousePressEvent): Store the offset from the layer's
+        resizing corner where dragging has started.
+        (WebCore::FrameView::handleMouseMoveEvent): Pass the stored offset to the
+        layer's resize method.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::resize): Added an offset parameter, which is added to
+        the mouse location.
+        For objects that may have intrinsic margins applied to them,
+        added code to lift the margins into the object's style in order to keep them
+        constant.
+        Changed to take the content size as the base size if the box-sizing property
+        is content-box.
+        (WebCore::RenderLayer::offsetFromResizeCorner): Added. Returns the offset of the
+        given point from the corner that tracks the mouse when resizing.
+        * rendering/RenderLayer.h:
+
 2006-06-24  Mitz Pettel  <opendarwin.org@mitzpettel.com>
 
         Reviewed by Darin, landed by ap.
index 666d715b05e32ecf9bd82e15fa57015bbf870397..4a17b465c4aa173e506eda3917070723a9a19165 100644 (file)
@@ -137,6 +137,7 @@ public:
     Timer<FrameView> hoverTimer;
     
     RenderLayer* m_resizeLayer;
+    IntSize offsetFromResizeCorner;
     
     // Used by objects during layout to communicate repaints that need to take place only
     // after all layout has been completed.
@@ -530,6 +531,7 @@ void FrameView::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
     if (layer && layer->isPointInResizeControl(p)) {
         layer->setInResizeMode(true);
         d->m_resizeLayer = layer;
+        d->offsetFromResizeCorner = layer->offsetFromResizeCorner(p);
         invalidateClick();
         return;  
     }
@@ -692,7 +694,7 @@ void FrameView::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent)
     bool swallowEvent = dispatchMouseEvent(mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true);
     
     if (d->m_resizeLayer && d->m_resizeLayer->inResizeMode())
-        d->m_resizeLayer->resize(mouseEvent);
+        d->m_resizeLayer->resize(mouseEvent, d->offsetFromResizeCorner);
 
     if (!swallowEvent)
         m_frame->handleMouseMoveEvent(mev);
index 1ed1f59d82e3bdf6dd31db5c0dddb82dfd801ea5..44ea9d8fa572daea19c51fee5d1f30126927761f 100644 (file)
@@ -55,6 +55,7 @@
 #include "HTMLNames.h"
 #include "PlatformMouseEvent.h"
 #include "RenderArena.h"
+#include "RenderFormElement.h"
 #include "RenderInline.h"
 #include "RenderTheme.h"
 #include "RenderView.h"
@@ -800,7 +801,7 @@ bool RenderLayer::shouldAutoscroll()
     return false;
 }
 
-void RenderLayer::resize(const PlatformMouseEvent& evt)
+void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& offsetFromResizeCorner)
 {
     if (!inResizeMode() || !renderer()->hasOverflowClip() || m_object->style()->resize() == RESIZE_NONE)
         return;
@@ -814,6 +815,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt)
     // the cursor in view.
 
     IntPoint currentPoint = m_object->document()->view()->viewportToContents(evt.pos());
+    currentPoint += offsetFromResizeCorner;
 
     int x;
     int y;
@@ -827,13 +829,25 @@ void RenderLayer::resize(const PlatformMouseEvent& evt)
     // Set the width and height for the shadow ancestor node.  This is necessary for textareas since the resizable layer is on the inner div.
     // For non-shadow content, this will set the width and height on the original node.
     RenderObject* renderer = m_object->node()->shadowAncestorNode()->renderer();
-    if (diffWidth && (m_object->style()->resize() == RESIZE_HORIZONTAL || m_object->style()->resize() == RESIZE_BOTH))
-        static_cast<Element*>(m_object->node()->shadowAncestorNode())->style()->setProperty(CSS_PROP_WIDTH, 
-                                                                                String::number(renderer->width() + diffWidth) + "px", false, ec);
+    if (diffWidth && (m_object->style()->resize() == RESIZE_HORIZONTAL || m_object->style()->resize() == RESIZE_BOTH)) {
+        CSSStyleDeclaration* style = static_cast<Element*>(m_object->node()->shadowAncestorNode())->style();
+        if (renderer->style()->hasAppearance() || renderer->isFormElement() && static_cast<RenderFormElement*>(renderer)->canHaveIntrinsicMargins()) {
+            style->setProperty(CSS_PROP_MARGIN_LEFT, String::number(renderer->marginLeft()) + "px", false, ec);
+            style->setProperty(CSS_PROP_MARGIN_RIGHT, String::number(renderer->marginRight()) + "px", false, ec);
+        }
+        int baseWidth = renderer->width() - (renderer->style()->boxSizing() == BORDER_BOX ? 0 : renderer->borderLeft() + renderer->paddingLeft() + renderer->borderRight() + renderer->paddingRight());
+        style->setProperty(CSS_PROP_WIDTH, String::number(baseWidth + diffWidth) + "px", false, ec);
+    }
 
-    if (diffHeight && (m_object->style()->resize() == RESIZE_VERTICAL || m_object->style()->resize() == RESIZE_BOTH))
-        static_cast<Element*>(m_object->node()->shadowAncestorNode())->style()->setProperty(CSS_PROP_HEIGHT, 
-                                                                                String::number(renderer->height() + diffHeight) + "px", false, ec);
+    if (diffHeight && (m_object->style()->resize() == RESIZE_VERTICAL || m_object->style()->resize() == RESIZE_BOTH)) {
+        CSSStyleDeclaration* style = static_cast<Element*>(m_object->node()->shadowAncestorNode())->style();
+        if (renderer->style()->hasAppearance() || renderer->isFormElement() && static_cast<RenderFormElement*>(renderer)->canHaveIntrinsicMargins()) {
+            style->setProperty(CSS_PROP_MARGIN_TOP, String::number(renderer->marginTop()) + "px", false, ec);
+            style->setProperty(CSS_PROP_MARGIN_BOTTOM, String::number(renderer->marginBottom()) + "px", false, ec);
+        }
+        int baseHeight = renderer->height() - (renderer->style()->boxSizing() == BORDER_BOX ? 0 : renderer->borderTop() + renderer->paddingTop() + renderer->borderBottom() + renderer->paddingBottom());
+        style->setProperty(CSS_PROP_HEIGHT, String::number(baseHeight + diffHeight) + "px", false, ec);
+    }
     
     ASSERT(ec == 0);
 
@@ -923,6 +937,15 @@ bool RenderLayer::isPointInResizeControl(const IntPoint& p)
     return resizeControlRect().contains(IntRect(p, IntSize()));
 }
 
+IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& p) const
+{
+    // Currently the resize corner is always the bottom right corner
+    int x = width();
+    int y = height();
+    convertToLayerCoords(root(), x, y);
+    return IntSize(x - p.x(), y - p.y());
+}
+
 void RenderLayer::positionResizeControl()
 {
     if (m_object->hasOverflowClip() && m_object->style()->resize() != RESIZE_NONE) {
index 55e941337c5efa598d64ab584179439f86cb00a3..ef68d09106e1701090f9cd5bc55373b3e2481551 100644 (file)
@@ -241,6 +241,7 @@ public:
     void positionScrollbars(const IntRect& absBounds);
     void positionResizeControl();
     bool isPointInResizeControl(const IntPoint&);
+    IntSize offsetFromResizeCorner(const IntPoint&) const;
     void paintScrollbars(GraphicsContext*, const IntRect& damageRect);
     void paintResizeControl(GraphicsContext*);
     void updateScrollInfoAfterLayout();
@@ -250,7 +251,7 @@ public:
     bool shouldAutoscroll();
     IntRect resizeControlRect() { return m_resizeControlRect; }
     void setResizeControlRect(const IntRect& r) { m_resizeControlRect = r; }
-    void resize(const PlatformMouseEvent&);
+    void resize(const PlatformMouseEvent&, const IntSize&);
     bool inResizeMode() const { return m_inResizeMode; }
     void setInResizeMode(bool b) { m_inResizeMode = b; }