[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

commit-queue at webkit.org commit-queue at webkit.org
Wed Dec 22 13:20:51 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 74bd2e8bcf9aad6f22ee7ff460a65ae4195b5713
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sun Sep 12 11:16:14 2010 +0000

    2010-09-12  Mario Sanchez Prada  <msanchez at igalia.com>
    
            Reviewed by Martin Robinson.
    
            [Gtk] get_n_selections and get_selection fail when selecting text across object boundaries
            https://bugs.webkit.org/show_bug.cgi?id=26991
    
            Fix AtkText getNSelections() and getSelection() to work properly
    
            * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
            (selectionBelongsToObject): Check that both the selection intersects
            the node AND that the selection is not just "touching" one of the
            boundaries for the selected node. We want to check whether the
            node is actually inside the region, at least partially
            (getSelectionOffsetsForObject): New function to get the start and
            end offsets of a selection for a given accessible object.
            (webkit_accessible_text_get_selection): Return zero when both
            start and end offsets are equal, following the lead of GAIL.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@67320 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 75fdc6e..419fa48 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2010-09-12  Mario Sanchez Prada  <msanchez at igalia.com>
+
+        Reviewed by Martin Robinson.
+
+        [Gtk] get_n_selections and get_selection fail when selecting text across object boundaries
+        https://bugs.webkit.org/show_bug.cgi?id=26991
+
+        Fix AtkText getNSelections() and getSelection() to work properly
+
+        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
+        (selectionBelongsToObject): Check that both the selection intersects
+        the node AND that the selection is not just "touching" one of the
+        boundaries for the selected node. We want to check whether the
+        node is actually inside the region, at least partially
+        (getSelectionOffsetsForObject): New function to get the start and
+        end offsets of a selection for a given accessible object.
+        (webkit_accessible_text_get_selection): Return zero when both
+        start and end offsets are equal, following the lead of GAIL.
+
 2010-09-11  Adam Barth  <abarth at webkit.org>
 
         Reviewed by Sam Weinig.
diff --git a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
index 90f363f..e818113 100644
--- a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
+++ b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
@@ -58,6 +58,7 @@
 #include "RenderListMarker.h"
 #include "RenderText.h"
 #include "TextEncoding.h"
+#include "TextIterator.h"
 #include <wtf/text/CString.h>
 #include <wtf/text/AtomicString.h>
 
@@ -1342,8 +1343,74 @@ static bool selectionBelongsToObject(AccessibilityObject* coreObject, VisibleSel
     if (!coreObject->isAccessibilityRenderObject())
         return false;
 
-    Node* node = static_cast<AccessibilityRenderObject*>(coreObject)->renderer()->node();
-    return node == selection.base().containerNode();
+    RefPtr<Range> range = selection.toNormalizedRange();
+    if (!range)
+        return false;
+
+    // We want to check that both the selection intersects the node
+    // AND that the selection is not just "touching" one of the
+    // boundaries for the selected node. We want to check whether the
+    // node is actually inside the region, at least partially
+    Node* node = coreObject->node();
+    Node* lastDescendant = node->lastDescendant();
+    ExceptionCode ec = 0;
+    return (range->intersectsNode(node, ec)
+            && (range->endContainer() != node || range->endOffset())
+            && (range->startContainer() != lastDescendant || range->startOffset() != lastOffsetInNode(lastDescendant)));
+}
+
+static void getSelectionOffsetsForObject(AccessibilityObject* coreObject, VisibleSelection& selection, gint& startOffset, gint& endOffset)
+{
+    if (!coreObject->isAccessibilityRenderObject())
+        return;
+
+    // Early return if the selection doesn't affect the selected node
+    if (!selectionBelongsToObject(coreObject, selection))
+        return;
+
+    // We need to find the exact start and end positions in the
+    // selected node that intersects the selection, to later on get
+    // the right values for the effective start and end offsets
+    ExceptionCode ec = 0;
+    Position nodeRangeStart;
+    Position nodeRangeEnd;
+    Node* node = coreObject->node();
+    RefPtr<Range> selRange = selection.toNormalizedRange();
+
+    // If the selection affects the selected node and its first
+    // possible position is also in the selection, we must set
+    // nodeRangeStart to that position, otherwise to the selection's
+    // start position (it would belong to the node anyway)
+    Node* firstLeafNode = node->firstDescendant();
+    if (selRange->isPointInRange(firstLeafNode, 0, ec))
+        nodeRangeStart = firstPositionInNode(firstLeafNode);
+    else
+        nodeRangeStart = selRange->startPosition();
+
+    // If the selection affects the selected node and its last
+    // possible position is also in the selection, we must set
+    // nodeRangeEnd to that position, otherwise to the selection's
+    // end position (it would belong to the node anyway)
+    Node* lastLeafNode = node->lastDescendant();
+    if (selRange->isPointInRange(lastLeafNode, lastOffsetInNode(lastLeafNode), ec))
+        nodeRangeEnd = lastPositionInNode(lastLeafNode);
+    else
+        nodeRangeEnd = selRange->endPosition();
+
+    // Set preliminar values for start and end offsets
+    startOffset = nodeRangeStart.offsetInContainerNode();
+    endOffset = nodeRangeEnd.offsetInContainerNode();
+
+    // If the end node is different then the start node, iterate over
+    // those among them to build the effective value for endOffset
+    if (nodeRangeStart.anchorNode() != nodeRangeEnd.anchorNode()) {
+        RefPtr<Range> nodeRange = Range::create(node->document(), nodeRangeStart, positionBeforeNode(nodeRangeEnd.anchorNode()));
+        for (TextIterator it(nodeRange.get()); !it.atEnd(); it.advance()) {
+            RefPtr<Range> range = it.range();
+            if (range->startContainer()->isTextNode())
+                endOffset += range->endOffset();
+        }
+    }
 }
 
 static gint webkit_accessible_text_get_n_selections(AtkText* text)
@@ -1351,6 +1418,10 @@ static gint webkit_accessible_text_get_n_selections(AtkText* text)
     AccessibilityObject* coreObject = core(text);
     VisibleSelection selection = coreObject->selection();
 
+    // Only range selections are needed for the purpose of this method
+    if (!selection.isRange())
+        return 0;
+
     // We don't support multiple selections for now, so there's only
     // two possibilities
     // Also, we don't want to do anything if the selection does not
@@ -1360,25 +1431,26 @@ static gint webkit_accessible_text_get_n_selections(AtkText* text)
     return !selectionBelongsToObject(coreObject, selection) || selection.isNone() ? 0 : 1;
 }
 
-static gchar* webkit_accessible_text_get_selection(AtkText* text, gint selection_num, gint* start_offset, gint* end_offset)
+static gchar* webkit_accessible_text_get_selection(AtkText* text, gint selectionNum, gint* startOffset, gint* endOffset)
 {
-    AccessibilityObject* coreObject = core(text);
-    VisibleSelection selection = coreObject->selection();
+    // Default values, unless the contrary is proved
+    *startOffset = *endOffset = 0;
 
     // WebCore does not support multiple selection, so anything but 0 does not make sense for now.
-    // Also, we don't want to do anything if the selection does not
-    // belong to the currently selected object. We have to check since
-    // there's no way to get the selection for a given object, only
-    // the global one (the API is a bit confusing)
-    if (selection_num != 0 || !selectionBelongsToObject(coreObject, selection)) {
-        *start_offset = *end_offset = 0;
+    if (selectionNum)
         return 0;
-    }
 
-    *start_offset = selection.start().offsetInContainerNode();
-    *end_offset = selection.end().offsetInContainerNode();
+    // Get the offsets of the selection for the selected object
+    AccessibilityObject* coreObject = core(text);
+    VisibleSelection selection = coreObject->selection();
+    getSelectionOffsetsForObject(coreObject, selection, *startOffset, *endOffset);
+
+    // Return 0 instead of "", as that's the expected result for
+    // this AtkText method when there's no selection
+    if (*startOffset == *endOffset)
+        return 0;
 
-    return webkit_accessible_text_get_text(text, *start_offset, *end_offset);
+    return webkit_accessible_text_get_text(text, *startOffset, *endOffset);
 }
 
 static gboolean webkit_accessible_text_add_selection(AtkText* text, gint start_offset, gint end_offset)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list