Logo Search packages:      
Sourcecode: xulrunner-1.9 version File versions

PRInt32 nsHyperTextAccessible::GetRelativeOffset ( nsIPresShell *  aPresShell,
nsIFrame aFromFrame,
PRInt32  aFromOffset,
nsIAccessible aFromAccessible,
nsSelectionAmount  aAmount,
nsDirection  aDirection,
PRBool  aNeedsStart 
) [protected, inherited]

Used by GetTextHelper() to move backward/forward from a given point by word/line/etc.

aPresShell the current presshell we're moving in
aFromFrame the starting frame we're moving from
aFromOffset the starting offset we're moving from
aFromAccessible the starting accessible we're moving from
aAmount how much are we moving (word/line/etc.) ?
aDirection forward or backward?
aNeedsStart for word and line cases, are we basing this on the start or end?
the resulting offset into this hypertext

Definition at line 642 of file nsHyperTextAccessible.cpp.

References nsHyperTextAccessible::DOMPointToHypertextOffset(), nsIFrame::GetContent(), nsIFrame::GetOffsets(), nsIFrame::GetType(), nsPeekOffsetStruct::mContentOffset, nsPeekOffsetStruct::mResultContent, nsIFrame::PeekOffset(), nsIAccessibleRole::ROLE_STATICTEXT, nsIAccessibleRole::ROLE_WHITESPACE, and nsPeekOffsetStruct::SetData().

  const PRBool kIsJumpLinesOk = PR_TRUE;          // okay to jump lines
  const PRBool kIsScrollViewAStop = PR_FALSE;     // do not stop at scroll views
  const PRBool kIsKeyboardSelect = PR_TRUE;       // is keyboard selection
  const PRBool kIsVisualBidi = PR_FALSE;          // use visual order for bidi text

  EWordMovementType wordMovementType = aNeedsStart ? eStartWord : eEndWord;
  if (aAmount == eSelectLine) {
    aAmount = (aDirection == eDirNext) ? eSelectEndLine : eSelectBeginLine;

  // Ask layout for the new node and offset, after moving the appropriate amount
  nsPeekOffsetStruct pos;

  nsresult rv;
  PRInt32 contentOffset = aFromOffset;
  if (IsText(aFromAccessible)) {
    nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(aFromAccessible));
    NS_ASSERTION(accessNode, "nsIAccessible doesn't support nsPIAccessNode");

    nsIFrame *frame = accessNode->GetFrame();
    NS_ENSURE_TRUE(frame, -1);
    if (frame->GetType() == nsAccessibilityAtoms::textFrame) {
      rv = RenderedToContentOffset(frame, aFromOffset, &contentOffset);
      NS_ENSURE_SUCCESS(rv, -1);

  pos.SetData(aAmount, aDirection, contentOffset,
              0, kIsJumpLinesOk, kIsScrollViewAStop, kIsKeyboardSelect, kIsVisualBidi,
  rv = aFromFrame->PeekOffset(&pos);
  if (NS_FAILED(rv)) {
    if (aDirection == eDirPrevious) {
      // Use passed-in frame as starting point in failure case for now,
      // this is a hack to deal with starting on a list bullet frame,
      // which fails in PeekOffset() because the line iterator doesn't see it.
      // XXX Need to look at our overall handling of list bullets, which are an odd case
      pos.mResultContent = aFromFrame->GetContent();
      PRInt32 endOffsetUnused;
      aFromFrame->GetOffsets(pos.mContentOffset, endOffsetUnused);
    else {
      return -1;

  // Turn the resulting node and offset into a hyperTextOffset
  PRInt32 hyperTextOffset;
  nsCOMPtr<nsIDOMNode> resultNode = do_QueryInterface(pos.mResultContent);
  NS_ENSURE_TRUE(resultNode, -1);

  nsCOMPtr<nsIAccessible> finalAccessible;
  rv = DOMPointToHypertextOffset(resultNode, pos.mContentOffset, &hyperTextOffset, getter_AddRefs(finalAccessible));
  // If finalAccessible == nsnull, then DOMPointToHypertextOffset() searched through the hypertext
  // children without finding the node/offset position

  if (!finalAccessible && aDirection == eDirPrevious) {
    // If we reached the end during search, this means we didn't find the DOM point
    // and we're actually at the start of the paragraph
    hyperTextOffset = 0;
  else if (aAmount == eSelectBeginLine) {
    // For line selection with needsStart, set start of line exactly to line break
    if (pos.mContentOffset == 0 && mFirstChild && 
        Role(mFirstChild) == nsIAccessibleRole::ROLE_STATICTEXT &&
        TextLength(mFirstChild) == hyperTextOffset) {
      // XXX Bullet hack -- we should remove this once list bullets use anonymous content
      hyperTextOffset = 0;
    if (!aNeedsStart && hyperTextOffset > 0) {
      -- hyperTextOffset;
  else if (aAmount == eSelectEndLine && finalAccessible) { 
    // If not at very end of hypertext, we may need change the end of line offset by 1, 
    // to make sure we are in the right place relative to the line ending
    if (Role(finalAccessible) == nsIAccessibleRole::ROLE_WHITESPACE) {  // Landed on <br> hard line break
      // if aNeedsStart, set end of line exactly 1 character past line break
      // XXX It would be cleaner if we did not have to have the hard line break check,
      // and just got the correct results from PeekOffset() for the <br> case -- the returned offset should
      // come after the new line, as it does in other cases.
      ++ hyperTextOffset;  // Get past hard line break
    // We are now 1 character past the line break
    if (!aNeedsStart) {
      -- hyperTextOffset;

  return hyperTextOffset;

Generated by  Doxygen 1.6.0   Back to index