already_AddRefed<nsIAccessibleEvent> a11y::MakeXPCEvent(AccEvent* aEvent) { DocAccessible* doc = aEvent->GetDocAccessible(); Accessible* acc = aEvent->GetAccessible(); nsINode* node = acc->GetNode(); nsIDOMNode* domNode = node ? node->AsDOMNode() : nullptr; bool fromUser = aEvent->IsFromUserInput(); uint32_t type = aEvent->GetEventType(); uint32_t eventGroup = aEvent->GetEventGroups(); nsCOMPtr<nsIAccessibleEvent> xpEvent; if (eventGroup & (1 << AccEvent::eStateChangeEvent)) { AccStateChangeEvent* sc = downcast_accEvent(aEvent); bool extra = false; uint32_t state = nsAccUtils::To32States(sc->GetState(), &extra); xpEvent = new xpcAccStateChangeEvent(type, acc, doc, domNode, fromUser, state, extra, sc->IsStateEnabled()); return xpEvent.forget(); } if (eventGroup & (1 << AccEvent::eTextChangeEvent)) { AccTextChangeEvent* tc = downcast_accEvent(aEvent); nsString text; tc->GetModifiedText(text); xpEvent = new xpcAccTextChangeEvent(type, acc, doc, domNode, fromUser, tc->GetStartOffset(), tc->GetLength(), tc->IsTextInserted(), text); return xpEvent.forget(); } if (eventGroup & (1 << AccEvent::eHideEvent)) { AccHideEvent* hideEvent = downcast_accEvent(aEvent); xpEvent = new xpcAccHideEvent(type, acc, doc, domNode, fromUser, hideEvent->TargetParent(), hideEvent->TargetNextSibling(), hideEvent->TargetPrevSibling()); return xpEvent.forget(); } if (eventGroup & (1 << AccEvent::eCaretMoveEvent)) { AccCaretMoveEvent* cm = downcast_accEvent(aEvent); xpEvent = new xpcAccCaretMoveEvent(type, acc, doc, domNode, fromUser, cm->GetCaretOffset()); return xpEvent.forget(); } if (eventGroup & (1 << AccEvent::eVirtualCursorChangeEvent)) { AccVCChangeEvent* vcc = downcast_accEvent(aEvent); xpEvent = new xpcAccVirtualCursorChangeEvent(type, acc, doc, domNode, fromUser, vcc->OldAccessible(), vcc->OldStartOffset(), vcc->OldEndOffset(), vcc->Reason()); return xpEvent.forget(); } xpEvent = new xpcAccEvent(type, acc, doc, domNode, fromUser); return xpEvent.forget(); }
nsresult AccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent, AtkObject* aObject) { AccTextChangeEvent* event = downcast_accEvent(aEvent); NS_ENSURE_TRUE(event, NS_ERROR_FAILURE); int32_t start = event->GetStartOffset(); uint32_t length = event->GetLength(); bool isInserted = event->IsTextInserted(); bool isFromUserInput = aEvent->IsFromUserInput(); if (gAvailableAtkSignals == eUnknown) gAvailableAtkSignals = g_signal_lookup("text-insert", G_OBJECT_TYPE(aObject)) ? eHaveNewAtkTextSignals : eNoNewAtkSignals; if (gAvailableAtkSignals == eNoNewAtkSignals) { // XXX remove this code and the gHaveNewTextSignals check when we can // stop supporting old atk since it doesn't really work anyway // see bug 619002 const char* signal_name = oldTextChangeStrings[isFromUserInput][isInserted]; g_signal_emit_by_name(aObject, signal_name, start, length); } else { nsAutoString text; event->GetModifiedText(text); const char* signal_name = textChangedStrings[isFromUserInput][isInserted]; g_signal_emit_by_name(aObject, signal_name, start, length, NS_ConvertUTF16toUTF8(text).get()); } return NS_OK; }
nsresult HyperTextAccessibleWrap::HandleAccEvent(AccEvent* aEvent) { uint32_t eventType = aEvent->GetEventType(); if (eventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED || eventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) { Accessible* accessible = aEvent->GetAccessible(); if (accessible && accessible->IsHyperText()) { AccTextChangeEvent* event = downcast_accEvent(aEvent); HyperTextAccessibleWrap* text = static_cast<HyperTextAccessibleWrap*>(accessible->AsHyperText()); ia2AccessibleText::UpdateTextChangeData(text, event->IsTextInserted(), event->ModifiedText(), event->GetStartOffset(), event->GetLength()); } } return HyperTextAccessible::HandleAccEvent(aEvent); }
nsresult AccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent, AtkObject* aObject) { MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n")); AccTextChangeEvent* event = downcast_accEvent(aEvent); NS_ENSURE_TRUE(event, NS_ERROR_FAILURE); PRInt32 start = event->GetStartOffset(); PRUint32 length = event->GetLength(); bool isInserted = event->IsTextInserted(); bool isFromUserInput = aEvent->IsFromUserInput(); char* signal_name = nsnull; if (gAvailableAtkSignals == eUnknown) gAvailableAtkSignals = g_signal_lookup("text-insert", G_OBJECT_TYPE(aObject)) ? eHaveNewAtkTextSignals : eNoNewAtkSignals; if (gAvailableAtkSignals == eNoNewAtkSignals) { // XXX remove this code and the gHaveNewTextSignals check when we can // stop supporting old atk since it doesn't really work anyway // see bug 619002 signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete", isFromUserInput ? "" : kNonUserInputEvent, NULL); g_signal_emit_by_name(aObject, signal_name, start, length); } else { nsAutoString text; event->GetModifiedText(text); signal_name = g_strconcat(isInserted ? "text-insert" : "text-remove", isFromUserInput ? "" : "::system", NULL); g_signal_emit_by_name(aObject, signal_name, start, length, NS_ConvertUTF16toUTF8(text).get()); } g_free(signal_name); return NS_OK; }
nsresult nsAccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent, AtkObject *aObject) { MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n")); AccTextChangeEvent* event = downcast_accEvent(aEvent); NS_ENSURE_TRUE(event, NS_ERROR_FAILURE); PRInt32 start = event->GetStartOffset(); PRUint32 length = event->GetLength(); PRBool isInserted = event->IsTextInserted(); PRBool isFromUserInput = aEvent->IsFromUserInput(); char *signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete", isFromUserInput ? "" : kNonUserInputEvent, NULL); g_signal_emit_by_name(aObject, signal_name, start, length); g_free (signal_name); return NS_OK; }
nsresult HyperTextAccessibleWrap::HandleAccEvent(AccEvent* aEvent) { uint32_t eventType = aEvent->GetEventType(); if (eventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED || eventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) { Accessible* accessible = aEvent->GetAccessible(); if (accessible && accessible->IsHyperText()) { sLastTextChangeAcc = accessible; if (!sLastTextChangeString) sLastTextChangeString = new nsString(); AccTextChangeEvent* event = downcast_accEvent(aEvent); event->GetModifiedText(*sLastTextChangeString); sLastTextChangeStart = event->GetStartOffset(); sLastTextChangeEnd = sLastTextChangeStart + event->GetLength(); sLastTextChangeWasInsert = event->IsTextInserted(); } } return HyperTextAccessible::HandleAccEvent(aEvent); }
nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) { auto accessible = static_cast<AccessibleWrap*>(aEvent->GetAccessible()); NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE); DocAccessibleWrap* doc = static_cast<DocAccessibleWrap*>(accessible->Document()); if (doc) { switch (aEvent->GetEventType()) { case nsIAccessibleEvent::EVENT_FOCUS: { if (DocAccessibleWrap* topContentDoc = doc->GetTopLevelContentDoc(accessible)) { topContentDoc->CacheFocusPath(accessible); } break; } case nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED: { AccVCChangeEvent* vcEvent = downcast_accEvent(aEvent); auto newPosition = static_cast<AccessibleWrap*>(vcEvent->NewAccessible()); if (newPosition) { if (DocAccessibleWrap* topContentDoc = doc->GetTopLevelContentDoc(accessible)) { topContentDoc->CacheFocusPath(newPosition); } } break; } } } nsresult rv = Accessible::HandleAccEvent(aEvent); NS_ENSURE_SUCCESS(rv, rv); if (IPCAccessibilityActive()) { return NS_OK; } // The accessible can become defunct if we have an xpcom event listener // which decides it would be fun to change the DOM and flush layout. if (accessible->IsDefunct() || !accessible->IsBoundToParent()) { return NS_OK; } if (doc) { if (!nsCoreUtils::IsContentDocument(doc->DocumentNode())) { return NS_OK; } } SessionAccessibility* sessionAcc = SessionAccessibility::GetInstanceFor(accessible); if (!sessionAcc) { return NS_OK; } switch (aEvent->GetEventType()) { case nsIAccessibleEvent::EVENT_FOCUS: sessionAcc->SendFocusEvent(accessible); break; case nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED: { AccVCChangeEvent* vcEvent = downcast_accEvent(aEvent); auto newPosition = static_cast<AccessibleWrap*>(vcEvent->NewAccessible()); auto oldPosition = static_cast<AccessibleWrap*>(vcEvent->OldAccessible()); if (sessionAcc && newPosition) { if (oldPosition != newPosition) { if (vcEvent->Reason() == nsIAccessiblePivot::REASON_POINT) { sessionAcc->SendHoverEnterEvent(newPosition); } else { sessionAcc->SendAccessibilityFocusedEvent(newPosition); } } if (vcEvent->BoundaryType() != nsIAccessiblePivot::NO_BOUNDARY) { sessionAcc->SendTextTraversedEvent( newPosition, vcEvent->NewStartOffset(), vcEvent->NewEndOffset()); } } break; } case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED: { AccCaretMoveEvent* event = downcast_accEvent(aEvent); sessionAcc->SendTextSelectionChangedEvent(accessible, event->GetCaretOffset()); break; } case nsIAccessibleEvent::EVENT_TEXT_INSERTED: case nsIAccessibleEvent::EVENT_TEXT_REMOVED: { AccTextChangeEvent* event = downcast_accEvent(aEvent); sessionAcc->SendTextChangedEvent( accessible, event->ModifiedText(), event->GetStartOffset(), event->GetLength(), event->IsTextInserted(), event->IsFromUserInput()); break; } case nsIAccessibleEvent::EVENT_STATE_CHANGE: { AccStateChangeEvent* event = downcast_accEvent(aEvent); auto state = event->GetState(); if (state & states::CHECKED) { sessionAcc->SendClickedEvent(accessible, event->IsStateEnabled()); } if (state & states::SELECTED) { sessionAcc->SendSelectedEvent(accessible, event->IsStateEnabled()); } if (state & states::BUSY) { sessionAcc->SendWindowStateChangedEvent(accessible); } break; } case nsIAccessibleEvent::EVENT_SCROLLING: { AccScrollingEvent* event = downcast_accEvent(aEvent); sessionAcc->SendScrollingEvent(accessible, event->ScrollX(), event->ScrollY(), event->MaxScrollX(), event->MaxScrollY()); break; } case nsIAccessibleEvent::EVENT_SHOW: case nsIAccessibleEvent::EVENT_HIDE: { AccMutationEvent* event = downcast_accEvent(aEvent); auto parent = static_cast<AccessibleWrap*>(event->Parent()); sessionAcc->SendWindowContentChangedEvent(parent); break; } default: break; } return NS_OK; }