PresShell::ScrollFrameIntoView(nsIFrame *aFrame, PRIntn   aVPercent, PRIntn   aHPercent) const
PresShell::ScrollFrameIntoView(nsIFrame *aFrame)
PresShell::ScrollFrameIntoView(nsIFrame *aFrame,                               PRIntn   aVPercent,                                PRIntn   aHPercent) const{  if (!aFrame) {    return NS_ERROR_NULL_POINTER;  }  // Before we scroll the frame into view, ask the command dispatcher  // if we're resetting focus because a window just got an activate  // event. If we are, we do not want to scroll the frame into view.  // Example: The user clicks on an anchor, and then deactivates the   // window. When they reactivate the window, the expected behavior  // is not for the anchor link to scroll back into view. That is what  // this check is preventing.  // XXX: The dependency on the command dispatcher needs to be fixed.  nsCOMPtr<nsIContent> content;  aFrame->GetContent(getter_AddRefs(content));  if(content) {    nsCOMPtr<nsIDocument> document;    content->GetDocument(getter_AddRefs(document));    if(document){      nsCOMPtr<nsIFocusController> focusController;      nsCOMPtr<nsIScriptGlobalObject> ourGlobal;      document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));      nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);      if(ourWindow) {        ourWindow->GetRootFocusController(getter_AddRefs(focusController));        if (focusController) {          PRBool dontScroll;          focusController->GetSuppressFocusScroll(&dontScroll);          if(dontScroll)            return NS_OK;        }      }    }  }  // This is a two-step process.  // Step 1: Find the bounds of the rect we want to scroll into view.  For  //         example, for an inline frame we want to scroll in the whole line.  // Step 2: Walk the views that are parents of the frame and scroll them  //         appropriately.    nsRect  frameBounds;  aFrame->GetRect(frameBounds);  nsPoint offset;  nsIView* closestView;  aFrame->GetOffsetFromView(mPresContext, offset, &closestView);  frameBounds.MoveTo(offset);  // If this is an inline frame, we need to change the top of the  // bounds to include the whole line.  nsCOMPtr<nsIAtom> frameType;  nsIFrame *prevFrame = aFrame;  nsIFrame *frame = aFrame;  while (frame && (frame->GetFrameType(getter_AddRefs(frameType)),                   frameType == nsLayoutAtoms::inlineFrame)) {    prevFrame = frame;    prevFrame->GetParent(&frame);  }  if (frame != aFrame &&      frame &&      frameType == nsLayoutAtoms::blockFrame) {    // find the line containing aFrame and increase the top of |offset|.    nsCOMPtr<nsILineIterator> lines( do_QueryInterface(frame) );    if (lines) {      PRInt32 index = -1;      lines->FindLineContaining(prevFrame, &index);      if (index >= 0) {        nsIFrame *trash1;        PRInt32 trash2;        nsRect lineBounds;        PRUint32 trash3;        if (NS_SUCCEEDED(lines->GetLine(index, &trash1, &trash2,                                        lineBounds, &trash3))) {          nsPoint blockOffset;          nsIView* blockView;          frame->GetOffsetFromView(mPresContext, blockOffset, &blockView);          if (blockView == closestView) {            // XXX If views not equal, this is hard.  Do we want to bother?            nscoord newoffset = lineBounds.y + blockOffset.y;            if (newoffset < frameBounds.y)              frameBounds.y = newoffset;          }        }      }    }  }#ifdef DEBUG  if (closestView) {    nsIScrollableView* _testView = nsnull;    CallQueryInterface(closestView, &_testView);    NS_ASSERTION(!_testView,                 "What happened to the scrolled view?  "                 "The frame should not be directly in the scrolling view!");  }#endif    // Walk up the view hierarchy.  Make sure to add the view's position  // _after_ we get the parent and see whether it's scrollable.  We want to  // make sure to get the scrolled view's position after it has been scrolled.  nsIScrollableView* scrollingView = nsnull;  while (closestView) {    nsIView* parent;    closestView->GetParent(parent);    if (parent) {      CallQueryInterface(parent, &scrollingView);      if (scrollingView) {        ScrollViewToShowRect(scrollingView, frameBounds, aVPercent, aHPercent);      }    }    nscoord x, y;    closestView->GetPosition(&x, &y);    frameBounds.MoveBy(x, y);    closestView = parent;  }  return NS_OK;}