Changeset 74025 in webkit
- Timestamp:
- Dec 14, 2010 7:35:22 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r74021 r74025 1 2010-12-14 Mario Sanchez Prada <msanchez@igalia.com> 2 3 Reviewed by Xan Lopez. 4 5 [Gtk] Implement STATE_FOCUSED, STATE_FOCUSABLE, and corresponding events for text objects 6 https://bugs.webkit.org/show_bug.cgi?id=27048 7 8 Added a new GTK-specific test to check focus{able|ed} states are 9 properly set when moving the caret across text objects. 10 11 * platform/gtk/accessibility/caret-browsing-text-focus-expected.txt: Added. 12 * platform/gtk/accessibility/caret-browsing-text-focus.html: Added. 13 1 14 2010-12-14 Pavel Feldman <pfeldman@chromium.org> 2 15 -
trunk/WebCore/ChangeLog
r74022 r74025 1 2010-12-14 Mario Sanchez Prada <msanchez@igalia.com> 2 3 Reviewed by Xan Lopez. 4 5 [Gtk] Implement STATE_FOCUSED, STATE_FOCUSABLE, and corresponding events for text objects 6 https://bugs.webkit.org/show_bug.cgi?id=27048 7 8 Handle focus change for text objects based in caret changes. 9 10 As text objects (such as paragraphs) seem not to accept focus in 11 WebCore in the same way other objects (text controls) do, a 12 Gtk-specific workaround is needed to expose this states and the 13 related events to ATK-based assistive technologies. 14 15 Test: platform/gtk/accessibility/caret-browsing-text-focus.html 16 17 Ensure that text objects are exposed with the ATK_STATE_FOCUSABLE 18 state, and that the ATK_STATE_FOCUSED state is added to those 19 text objects containing the currently active caret selection. 20 21 * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp: 22 (selectionBelongsToObject): Moved upwards to use it from 23 the new isTextWithCaret() function. 24 (isTextWithCaret): New, checks whether an accessibility object 25 represents a text object with the current caret selection on it. 26 (setAtkStateSetFromCoreObject): Add the ATK_STATE_FOCUSED state 27 when also when isTextWithCaret(coreObject) returns true. 28 (webkit_accessible_ref_state_set): Add the ATK_STATE_FOCUSABLE 29 state to text objects and those with the ATK_ROLE_PARAGRAPH role. 30 (webkit_accessible_text_get_n_selections): Optimize return expression. 31 32 Make sure the proper events associated to a change of focus are 33 emitted, based on caret changes across different accessibility 34 objects. Also, refactored the code in more manageable and 35 understandable helper functions. 36 37 * editing/gtk/SelectionControllerGtk.cpp: 38 (WebCore::emitTextSelectionChange): New, includes the specific 39 code formerly placed in notifyAccessibilityForSelectionChange() to 40 emit the 'text-caret-moved' and 'text-selection-change' signals. 41 (WebCore::maybeEmitTextFocusChange): New, takes care of emitting 42 the 'focus-event' and 'state-changed::focused' signals when 43 needed, that is, when a change in the selection happens across 44 different accessible objects. 45 (WebCore::SelectionController::notifyAccessibilityForSelectionChange): 46 Refactored some code here, by using the new helper functions. 47 1 48 2010-12-14 Ilya Tikhonovsky <loislo@chromium.org> 2 49 -
trunk/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
r73825 r74025 60 60 #include "RenderText.h" 61 61 #include "SelectElement.h" 62 #include "Settings.h" 62 63 #include "TextEncoding.h" 63 64 #include "TextIterator.h" … … 478 479 } 479 480 481 static bool selectionBelongsToObject(AccessibilityObject* coreObject, VisibleSelection& selection) 482 { 483 if (!coreObject || !coreObject->isAccessibilityRenderObject()) 484 return false; 485 486 if (selection.isNone()) 487 return false; 488 489 RefPtr<Range> range = selection.toNormalizedRange(); 490 if (!range) 491 return false; 492 493 // We want to check that both the selection intersects the node 494 // AND that the selection is not just "touching" one of the 495 // boundaries for the selected node. We want to check whether the 496 // node is actually inside the region, at least partially. 497 Node* node = coreObject->node(); 498 Node* lastDescendant = node->lastDescendant(); 499 ExceptionCode ec = 0; 500 return (range->intersectsNode(node, ec) 501 && (range->endContainer() != node || range->endOffset()) 502 && (range->startContainer() != lastDescendant || range->startOffset() != lastOffsetInNode(lastDescendant))); 503 } 504 505 static bool isTextWithCaret(AccessibilityObject* coreObject) 506 { 507 if (!coreObject || !coreObject->isAccessibilityRenderObject()) 508 return false; 509 510 Document* document = coreObject->document(); 511 if (!document) 512 return false; 513 514 Frame* frame = document->frame(); 515 if (!frame) 516 return false; 517 518 Settings* settings = frame->settings(); 519 if (!settings || !settings->caretBrowsingEnabled()) 520 return false; 521 522 // Check text objects and paragraphs only. 523 AtkObject* axObject = coreObject->wrapper(); 524 AtkRole role = axObject ? atk_object_get_role(axObject) : ATK_ROLE_INVALID; 525 if (role != ATK_ROLE_TEXT && role != ATK_ROLE_PARAGRAPH) 526 return false; 527 528 // Finally, check whether the caret is set in the current object. 529 VisibleSelection selection = coreObject->selection(); 530 if (!selection.isCaret()) 531 return false; 532 533 return selectionBelongsToObject(coreObject, selection); 534 } 535 480 536 static void setAtkStateSetFromCoreObject(AccessibilityObject* coreObject, AtkStateSet* stateSet) 481 537 { … … 511 567 atk_state_set_add_state(stateSet, ATK_STATE_FOCUSABLE); 512 568 513 if (coreObject->isFocused() )569 if (coreObject->isFocused() || isTextWithCaret(coreObject)) 514 570 atk_state_set_add_state(stateSet, ATK_STATE_FOCUSED); 515 571 … … 580 636 } 581 637 638 // Text objects must be focusable. 639 AtkRole role = atk_object_get_role(object); 640 if (role == ATK_ROLE_TEXT || role == ATK_ROLE_PARAGRAPH) 641 atk_state_set_add_state(stateSet, ATK_STATE_FOCUSABLE); 642 582 643 setAtkStateSetFromCoreObject(coreObject, stateSet); 583 584 644 return stateSet; 585 645 } … … 1486 1546 } 1487 1547 1488 static bool selectionBelongsToObject(AccessibilityObject* coreObject, VisibleSelection& selection)1489 {1490 if (!coreObject->isAccessibilityRenderObject())1491 return false;1492 1493 RefPtr<Range> range = selection.toNormalizedRange();1494 if (!range)1495 return false;1496 1497 // We want to check that both the selection intersects the node1498 // AND that the selection is not just "touching" one of the1499 // boundaries for the selected node. We want to check whether the1500 // node is actually inside the region, at least partially1501 Node* node = coreObject->node();1502 Node* lastDescendant = node->lastDescendant();1503 ExceptionCode ec = 0;1504 return (range->intersectsNode(node, ec)1505 && (range->endContainer() != node || range->endOffset())1506 && (range->startContainer() != lastDescendant || range->startOffset() != lastOffsetInNode(lastDescendant)));1507 }1508 1509 1548 static void getSelectionOffsetsForObject(AccessibilityObject* coreObject, VisibleSelection& selection, gint& startOffset, gint& endOffset) 1510 1549 { … … 1570 1609 // there's no way to get the selection for a given object, only 1571 1610 // the global one (the API is a bit confusing) 1572 return !selectionBelongsToObject(coreObject, selection) || selection.isNone() ? 0 : 1;1611 return selectionBelongsToObject(coreObject, selection) ? 1 : 0; 1573 1612 } 1574 1613 -
trunk/WebCore/editing/gtk/SelectionControllerGtk.cpp
r68665 r74025 24 24 #include "AXObjectCache.h" 25 25 #include "Frame.h" 26 #include "RefPtr.h" 26 27 27 28 #include <gtk/gtk.h> … … 29 30 namespace WebCore { 30 31 32 static void emitTextSelectionChange(AccessibilityObject* object, VisibleSelection selection, int offset) 33 { 34 AtkObject* axObject = object->wrapper(); 35 if (!axObject || !ATK_IS_TEXT(axObject)) 36 return; 37 38 g_signal_emit_by_name(axObject, "text-caret-moved", offset); 39 if (selection.isRange()) 40 g_signal_emit_by_name(axObject, "text-selection-changed"); 41 } 42 43 static void maybeEmitTextFocusChange(PassRefPtr<AccessibilityObject> prpObject) 44 { 45 // This static variable is needed to keep track of the old object 46 // as per previous calls to this function, in order to properly 47 // decide whether to emit some signals or not. 48 DEFINE_STATIC_LOCAL(RefPtr<AccessibilityObject>, oldObject, ()); 49 50 RefPtr<AccessibilityObject> object = prpObject; 51 52 // Ensure the oldObject belongs to the same document that the 53 // current object so further comparisons make sense. Otherwise, 54 // just reset oldObject to 0 so it won't be taken into account in 55 // the immediately following call to this function. 56 if (object && oldObject && oldObject->document() != object->document()) 57 oldObject = 0; 58 59 AtkObject* axObject = object ? object->wrapper() : 0; 60 AtkObject* oldAxObject = oldObject ? oldObject->wrapper() : 0; 61 62 if (axObject != oldAxObject) { 63 if (oldAxObject && ATK_IS_TEXT(oldAxObject)) { 64 g_signal_emit_by_name(oldAxObject, "focus-event", false); 65 g_signal_emit_by_name(oldAxObject, "state-change", "focused", false); 66 } 67 if (axObject && ATK_IS_TEXT(axObject)) { 68 g_signal_emit_by_name(axObject, "focus-event", true); 69 g_signal_emit_by_name(axObject, "state-change", "focused", true); 70 } 71 } 72 73 // Update pointer to last focused object. 74 oldObject = object; 75 } 76 77 31 78 void SelectionController::notifyAccessibilityForSelectionChange() 32 79 { 33 if (AXObjectCache::accessibilityEnabled() && m_selection.start().isNotNull() && m_selection.end().isNotNull()) { 34 RenderObject* focusedNode = m_selection.end().node()->renderer(); 35 AccessibilityObject* accessibilityObject = m_frame->document()->axObjectCache()->getOrCreate(focusedNode); 80 if (!AXObjectCache::accessibilityEnabled()) 81 return; 36 82 37 // need to check this as getOrCreate could return 038 if (!accessibilityObject)39 83 // Reset lastFocuseNode and return for no valid selections. 84 if (!m_selection.start().isNotNull() || !m_selection.end().isNotNull()) 85 return; 40 86 41 int offset; 42 // Always report the events w.r.t. the non-linked unignored parent. (i.e. ignoreLinks == true) 43 AccessibilityObject* object = objectAndOffsetUnignored(accessibilityObject, offset, true); 44 if (!object) 45 return; 87 RenderObject* focusedNode = m_selection.end().node()->renderer(); 88 AccessibilityObject* accessibilityObject = m_frame->document()->axObjectCache()->getOrCreate(focusedNode); 46 89 47 AtkObject* wrapper = object->wrapper(); 48 if (ATK_IS_TEXT(wrapper)) { 49 g_signal_emit_by_name(wrapper, "text-caret-moved", offset); 50 if (m_selection.isRange()) 51 g_signal_emit_by_name(wrapper, "text-selection-changed"); 52 } 53 } 90 // Need to check this as getOrCreate could return 0, 91 if (!accessibilityObject) 92 return; 93 94 int offset; 95 // Always report the events w.r.t. the non-linked unignored parent. (i.e. ignoreLinks == true). 96 RefPtr<AccessibilityObject> object = objectAndOffsetUnignored(accessibilityObject, offset, true); 97 if (!object) 98 return; 99 100 // Emit relatedsignals. 101 emitTextSelectionChange(object.get(), m_selection, offset); 102 maybeEmitTextFocusChange(object.release()); 54 103 } 55 104 -
trunk/WebKitTools/ChangeLog
r74008 r74025 1 2010-12-14 Mario Sanchez Prada <msanchez@igalia.com> 2 3 Reviewed by Xan Lopez. 4 5 [Gtk] Implement STATE_FOCUSED, STATE_FOCUSABLE, and corresponding events for text objects 6 https://bugs.webkit.org/show_bug.cgi?id=27048 7 8 Add support in DRT for checking whether an accessibility UI 9 element is focusable and/or focused. Implemented for GTK. 10 11 * DumpRenderTree/AccessibilityUIElement.cpp: 12 (getIsFocusedCallback): New. 13 (getIsFocusableCallback): New. 14 (AccessibilityUIElement::getJSClass): Add the new available 15 callbacks for isFocused and isFocusable. 16 * DumpRenderTree/AccessibilityUIElement.h: 17 * DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp: 18 (AccessibilityUIElement::isFocused): New, implemented by checking 19 whether the related AtkState value is in the object's state set. 20 (AccessibilityUIElement::isFocusable): Ditto. 21 * DumpRenderTree/mac/AccessibilityUIElementMac.mm: 22 (AccessibilityUIElement::isFocused): New, dummy implementation. 23 (AccessibilityUIElement::isFocusable): Ditto. 24 * DumpRenderTree/win/AccessibilityUIElementWin.cpp: 25 (AccessibilityUIElement::isFocused): Ditto. 26 (AccessibilityUIElement::isFocusable): Ditto. 27 1 28 2010-12-14 Eric Seidel <eric@webkit.org> 2 29 -
trunk/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
r71792 r74025 663 663 { 664 664 return JSValueMakeBoolean(context, toAXElement(thisObject)->isRequired()); 665 } 666 667 static JSValueRef getIsFocusedCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*) 668 { 669 return JSValueMakeBoolean(context, toAXElement(thisObject)->isFocused()); 670 } 671 672 static JSValueRef getIsFocusableCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*) 673 { 674 return JSValueMakeBoolean(context, toAXElement(thisObject)->isFocusable()); 665 675 } 666 676 … … 876 886 { "isEnabled", getIsEnabledCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 877 887 { "isRequired", getIsRequiredCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 888 { "isFocused", getIsFocusedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 889 { "isFocusable", getIsFocusableCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 878 890 { "isSelected", getIsSelectedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 879 891 { "isSelectable", getIsSelectableCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, -
trunk/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
r71792 r74025 132 132 bool isRequired() const; 133 133 134 bool isFocused() const; 135 bool isFocusable() const; 134 136 bool isSelected() const; 135 137 bool isSelectable() const; -
trunk/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp
r73732 r74025 404 404 } 405 405 406 bool AccessibilityUIElement::isFocused() const 407 { 408 if (!ATK_IS_OBJECT(m_element)) 409 return false; 410 411 PlatformRefPtr<AtkStateSet> stateSet = adoptPlatformRef(atk_object_ref_state_set(ATK_OBJECT(m_element))); 412 gboolean isFocused = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSED); 413 414 return isFocused; 415 } 416 406 417 bool AccessibilityUIElement::isSelected() const 407 418 { … … 655 666 } 656 667 668 bool AccessibilityUIElement::isFocusable() const 669 { 670 if (!ATK_IS_OBJECT(m_element)) 671 return false; 672 673 PlatformRefPtr<AtkStateSet> stateSet = adoptPlatformRef(atk_object_ref_state_set(ATK_OBJECT(m_element))); 674 gboolean isFocusable = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSABLE); 675 676 return isFocusable; 677 } 678 657 679 bool AccessibilityUIElement::isSelectable() const 658 680 { -
trunk/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
r70792 r74025 762 762 } 763 763 764 bool AccessibilityUIElement::isFocused() const 765 { 766 // FIXME: implement 767 return false; 768 } 769 764 770 bool AccessibilityUIElement::isSelected() const 765 771 { … … 1182 1188 } 1183 1189 1190 bool AccessibilityUIElement::isFocusable() const 1191 { 1192 // FIXME: implement 1193 return false; 1194 } 1195 1184 1196 bool AccessibilityUIElement::isSelectable() const 1185 1197 { -
trunk/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
r71792 r74025 330 330 } 331 331 332 bool AccessibilityUIElement::isFocused() const 333 { 334 // FIXME: implement 335 return false; 336 } 337 332 338 bool AccessibilityUIElement::isSelected() const 333 339 { … … 606 612 } 607 613 614 bool AccessibilityUIElement::isFocusable() const 615 { 616 // FIXME: implement 617 return false; 618 } 619 608 620 bool AccessibilityUIElement::isSelectable() const 609 621 {
Note: See TracChangeset
for help on using the changeset viewer.