Esempio n. 1
0
void SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent) {
  // Fire selection change event if it's not pure caret-move selection change,
  // i.e. the accessible has or had not collapsed selection.
  AccTextSelChangeEvent* event = downcast_accEvent(aEvent);
  if (!event->IsCaretMoveOnly()) nsEventShell::FireEvent(aEvent);

  // Fire caret move event if there's a caret in the selection.
  nsINode* caretCntrNode = nsCoreUtils::GetDOMNodeFromDOMPoint(
      event->mSel->GetFocusNode(), event->mSel->FocusOffset());
  if (!caretCntrNode) return;

  HyperTextAccessible* caretCntr = nsAccUtils::GetTextContainer(caretCntrNode);
  NS_ASSERTION(
      caretCntr,
      "No text container for focus while there's one for common ancestor?!");
  if (!caretCntr) return;

  Selection* selection = caretCntr->DOMSelection();

  // XXX Sometimes we can't get a selection for caretCntr, in that case assume
  // event->mSel is correct.
  if (!selection) selection = event->mSel;

  mCaretOffset = caretCntr->DOMPointToOffset(selection->GetFocusNode(),
                                             selection->FocusOffset());
  mAccWithCaret = caretCntr;
  if (mCaretOffset != -1) {
    RefPtr<AccCaretMoveEvent> caretMoveEvent =
        new AccCaretMoveEvent(caretCntr, mCaretOffset, aEvent->FromUserInput());
    nsEventShell::FireEvent(caretMoveEvent);
  }
}
void
AccessibleCaretManager::UpdateCaretsForCursorMode()
{
  AC_LOG("%s, selection: %p", __FUNCTION__, GetSelection());

  nsRefPtr<nsCaret> caret = mPresShell->GetCaret();
  if (!caret || !caret->IsVisible()) {
    HideCarets();
    return;
  }

  nsRefPtr<nsFrameSelection> fs = GetFrameSelection();
  Selection* selection = GetSelection();
  if (!fs || !selection) {
    HideCarets();
    return;
  }

  nsINode* focusNode = selection->GetFocusNode();
  nsIContent* focusContent = focusNode->AsContent();
  uint32_t focusOffset = selection->FocusOffset();

  nsIFrame* frame = nullptr;
  int32_t offset = 0;
  nsresult rv = nsCaret::GetCaretFrameForNodeOffset(
    fs, focusContent, focusOffset, fs->GetHint(), fs->GetCaretBidiLevel(),
    &frame, &offset);

  if (NS_FAILED(rv) || !frame) {
    HideCarets();
    return;
  }

  Element* editingHost = frame->GetContent()->GetEditingHost();
  if (!editingHost) {
    HideCarets();
    return;
  }

  // No need to consider whether the caret's position is out of scrollport.
  // According to the spec, we need to explicitly hide it after the scrolling is
  // ended.
  bool oldSecondCaretVisible = mSecondCaret->IsLogicallyVisible();
  PositionChangedResult caretResult = mFirstCaret->SetPosition(frame, offset);
  mFirstCaret->SetSelectionBarEnabled(false);
  if (nsContentUtils::HasNonEmptyTextContent(
        editingHost, nsContentUtils::eRecurseIntoChildren)) {
    mFirstCaret->SetAppearance(Appearance::Normal);
  } else {
    mFirstCaret->SetAppearance(Appearance::NormalNotShown);
  }
  LaunchCaretTimeoutTimer();
  mSecondCaret->SetAppearance(Appearance::None);

  if ((caretResult == PositionChangedResult::Changed ||
      oldSecondCaretVisible) && !mActiveCaret) {
    DispatchCaretStateChangedEvent(CaretChangedReason::Updateposition);
  }
}