Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Static Protected Attributes
nsTypeAheadFind Class Reference

#include <nsTypeAheadFind.h>

Inheritance diagram for nsTypeAheadFind:
Inheritance graph
[legend]
Collaboration diagram for nsTypeAheadFind:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsTypeAheadFind ()
virtual ~nsTypeAheadFind ()
 NS_DEFINE_STATIC_CID_ACCESSOR (NS_TYPEAHEADFIND_CID)
NS_DECL_ISUPPORTS
NS_DECL_NSITYPEAHEADFIND
NS_DECL_NSIOBSERVER
NS_DECL_NSIDOMEVENTLISTENER
NS_DECL_NSISELECTIONLISTENER
NS_IMETHOD 
KeyDown (nsIDOMEvent *aKeyEvent)
 Processes a key pressed event.
NS_IMETHOD KeyUp (nsIDOMEvent *aKeyEvent)
 Processes a key release event.
NS_IMETHOD KeyPress (nsIDOMEvent *aKeyEvent)
 Processes a key typed event.
NS_IMETHOD HandleText (nsIDOMEvent *aTextEvent)
NS_IMETHOD HandleStartComposition (nsIDOMEvent *aCompositionEvent)
NS_IMETHOD HandleEndComposition (nsIDOMEvent *aCompositionEvent)
NS_IMETHOD HandleQueryComposition (nsIDOMEvent *aCompositionEvent)
NS_IMETHOD HandleQueryReconversion (nsIDOMEvent *aCompositionEvent)
NS_IMETHOD HandleQueryCaretRect (nsIDOMEvent *aCompositionEvent)
NS_IMETHOD ScrollPositionWillChange (nsIScrollableView *aView, nscoord aX, nscoord aY)
NS_IMETHOD ScrollPositionDidChange (nsIScrollableView *aView, nscoord aX, nscoord aY)
 nsTypeAheadFind ()
virtual ~nsTypeAheadFind ()
void setSelectionModeAndRepaint (in short toggle)
void collapseSelection ()
void startNewFind (in nsIDOMWindow aWindow, in boolean aLinksOnly)
 Manually start type ahead find mode.
void cancelFind ()
 Manually cancel type ahead find mode.
void setAutoStart (in nsIDOMWindow aWindow, in boolean aIsAutoStartOn)
 Will find as you type start automatically if the user types with the focus on page content other than a textfield or select? If autostart is off, the startNewFind() method can be used to enact type ahead find, as well as cmd_findTypeLinks or cmd_findTypeText.
boolean getAutoStart (in nsIDOMWindow aWindow)
void findNext (in boolean aReverse, in nsISupportsInterfacePointer aCallerWindowSupports)
 Find next recurrence if typeaheadfind was the last used find, as opposed to regular find.
unsigned short findNext ()
boolean backOneChar ()
void init (in nsIDocShell aDocShell)
unsigned short find (in AString aSearchString, in boolean aLinksOnly)
unsigned short findPrevious ()
void setDocShell (in nsIDocShell aDocShell)
void observe (in nsISupports aSubject, in string aTopic, in wstring aData)
 Observe will be called when there is a notification for the topic |aTopic|.
void handleEvent (in nsIDOMEvent event)
 This method is called whenever an event occurs of the type for which the EventListener interface was registered.
void notifySelectionChanged (in nsIDOMDocument doc, in nsISelection sel, in short reason)
void notify (in nsITimer timer)

Static Public Member Functions

static
NS_DECL_NSITIMERCALLBACK
nsTypeAheadFind
GetInstance ()
static void ReleaseInstance (void)
static PRBool IsTargetContentOkay (nsIContent *aContent)

Public Attributes

readonly attribute nsIDOMElement foundEditable
readonly attribute boolean isActive
 Is type ahead find mode currently on?
readonly attribute AString searchString
attribute boolean focusLinks
attribute boolean caseSensitive
readonly attribute nsIDOMElement foundLink
readonly attribute nsIDOMWindow currentWindow
const unsigned short FIND_FOUND = 0
const unsigned short FIND_NOTFOUND = 1
const unsigned short FIND_WRAPPED = 2
const short NO_REASON = 0
const short DRAG_REASON = 1
const short MOUSEDOWN_REASON = 2
const short MOUSEUP_REASON = 4
const short KEYPRESS_REASON = 8
const short SELECTALL_REASON = 16

Protected Member Functions

nsresult PrefsReset ()
nsresult HandleChar (PRUnichar aChar)
PRBool HandleBackspace ()
void SaveFind ()
void PlayNotFoundSound ()
void GetTopContentPresShell (nsIDocShellTreeItem *aTreeItem, nsIPresShell **aPresShell)
void GetStartWindow (nsIDOMWindow *aWindow, nsIDOMWindow **aStartWindow)
nsresult GetWebBrowserFind (nsIDOMWindow *aDOMWin, nsIWebBrowserFind **aWebBrowserFind)
void StartTimeout ()
nsresult Init ()
void Shutdown ()
nsresult UseInWindow (nsIDOMWindow *aDomWin)
void SetSelectionLook (nsIPresShell *aPresShell, PRBool aChangeColor, PRBool aEnabled)
void ResetGlobalAutoStart (PRBool aAutoStart)
void AttachDocListeners (nsIPresShell *aPresShell)
void RemoveDocListeners ()
void AttachWindowListeners (nsIDOMWindow *aDOMWin)
void RemoveWindowListeners (nsIDOMWindow *aDOMWin)
void GetChromeEventHandler (nsIDOMWindow *aDOMWin, nsIDOMEventTarget **aChromeTarget)
void RangeStartsInsideLink (nsIDOMRange *aRange, nsIPresShell *aPresShell, PRBool *aIsInsideLink, PRBool *aIsStartingLink)
nsresult GetTargetIfTypeAheadOkay (nsIDOMEvent *aEvent, nsIContent **aTargetContent, nsIPresShell **aTargetPresShell)
void GetSelection (nsIPresShell *aPresShell, nsISelectionController **aSelCon, nsISelection **aDomSel)
PRBool IsRangeVisible (nsIPresShell *aPresShell, nsPresContext *aPresContext, nsIDOMRange *aRange, PRBool aMustBeVisible, PRBool aGetTopVisibleLeaf, nsIDOMRange **aNewRange)
nsresult FindItNow (nsIPresShell *aPresShell, PRBool aIsRepeatingSameChar, PRBool aIsLinksOnly, PRBool aIsFirstVisiblePreferred)
nsresult GetSearchContainers (nsISupports *aContainer, PRBool aIsRepeatingSameChar, PRBool aIsFirstVisiblePreferred, PRBool aCanUseDocSelection, nsIPresShell **aPresShell, nsPresContext **aPresContext)
void DisplayStatus (PRBool aSuccess, nsIContent *aFocusedContent, PRBool aClearStatus, const PRUnichar *aText=nsnull)
nsresult GetTranslatedString (const nsAString &aKey, nsAString &aStringOut)
 NS_HIDDEN_ (already_AddRefed< nsIPresShell >) GetPresShell()
nsresult PrefsReset ()
void SaveFind ()
void PlayNotFoundSound ()
nsresult FindInternal (PRBool aFindBackwards, PRUint16 *aResult)
nsresult GetWebBrowserFind (nsIDocShell *aDocShell, nsIWebBrowserFind **aWebBrowserFind)
void RangeStartsInsideLink (nsIDOMRange *aRange, nsIPresShell *aPresShell, PRBool *aIsInsideLink, PRBool *aIsStartingLink)
void GetSelection (nsIPresShell *aPresShell, nsISelectionController **aSelCon, nsISelection **aDomSel)
PRBool FindFieldHasFocus (nsPresContext *aPresContext)
PRBool IsRangeVisible (nsIPresShell *aPresShell, nsPresContext *aPresContext, nsIDOMRange *aRange, PRBool aMustBeVisible, PRBool aGetTopVisibleLeaf, nsIDOMRange **aNewRange, PRBool *aUsesIndependentSelection)
nsresult FindItNow (nsIPresShell *aPresShell, PRBool aIsRepeatingSameChar, PRBool aIsLinksOnly, PRBool aIsFirstVisiblePreferred, PRBool aFindNext, PRUint16 *aResult)
nsresult GetSearchContainers (nsISupports *aContainer, nsISelectionController *aSelectionController, PRBool aIsRepeatingSameChar, PRBool aIsFirstVisiblePreferred, nsIPresShell **aPresShell, nsPresContext **aPresContext)
nsresult Cancel ()
 NS_HIDDEN_ (already_AddRefed< nsIPresShell >) GetPresShell()

Protected Attributes

nsString mTypeAheadBuffer
nsString mFindNextBuffer
nsString mIMEString
nsCString mNotFoundSoundURL
PRBool mIsFindAllowedInWindow
PRBool mAutoStartPref
PRBool mLinksOnlyPref
PRBool mStartLinksOnlyPref
PRPackedBool mLinksOnly
PRBool mIsTypeAheadOn
PRBool mCaretBrowsingOn
PRPackedBool mLiteralTextSearchOnly
PRPackedBool mDontTryExactMatch
PRPackedBool mAllTheSameChar
PRPackedBool mLinksOnlyManuallySet
PRPackedBool mIsFindingText
PRPackedBool mIsMenuBarActive
PRPackedBool mIsMenuPopupActive
PRPackedBool mIsFirstVisiblePreferred
PRPackedBool mIsIMETypeAheadActive
PRPackedBool mIsBackspaceProtectOn
PRInt32 mBadKeysSinceMatch
PRUnichar mLastBadChar
PRInt32 mRepeatingMode
PRInt32 mTimeoutLength
nsCOMPtr< nsISoundmSoundInterface
PRBool mIsSoundInitialized
nsCOMPtr< nsIDOMRangemStartFindRange
nsCOMPtr< nsIDOMRangemSearchRange
nsCOMPtr< nsIDOMRangemStartPointRange
nsCOMPtr< nsIDOMRangemEndPointRange
nsCOMPtr< nsIFindmFind
nsCOMPtr< nsIFindServicemFindService
nsCOMPtr< nsIStringBundlemStringBundle
nsCOMPtr< nsITimermTimer
nsCOMPtr< nsIFocusControllermFocusController
nsCOMPtr< nsISelectionmFocusedDocSelection
nsCOMPtr< nsISelectionControllermFocusedDocSelCon
nsCOMPtr< nsIDOMWindowmFocusedWindow
nsCOMPtr< nsIWeakReferencemFocusedWeakShell
nsCOMPtr< nsISupportsArraymManualFindWindows
nsCOMPtr< nsIDOMElementmFoundLink
nsCOMPtr< nsIDOMElementmFoundEditable
nsCOMPtr< nsIDOMWindowmCurrentWindow
PRUint32 mLastFindLength
nsCOMPtr< nsIWebBrowserFindmWebBrowserFind
nsWeakPtr mDocShell
nsWeakPtr mPresShell
nsWeakPtr mSelectionController

Static Protected Attributes

static nsTypeAheadFindsInstance = nsnull
static PRInt32 sAccelKey = -1

Detailed Description

Definition at line 83 of file nsTypeAheadFind.h.


Constructor & Destructor Documentation

Definition at line 169 of file nsTypeAheadFind.cpp.

{
  RemoveDocListeners();
  mTimer = nsnull;

  nsCOMPtr<nsIPrefBranch2> prefInternal(do_GetService(NS_PREFSERVICE_CONTRACTID));
  if (prefInternal) {
    prefInternal->RemoveObserver("accessibility.typeaheadfind", this);
    prefInternal->RemoveObserver("accessibility.browsewithcaret", this);
  }
}

Here is the call graph for this function:

virtual nsTypeAheadFind::~nsTypeAheadFind ( ) [virtual]

Member Function Documentation

void nsTypeAheadFind::AttachDocListeners ( nsIPresShell aPresShell) [protected]

Definition at line 2248 of file nsTypeAheadFind.cpp.

{
  if (!aPresShell) {
    return;
  }

  nsIViewManager* vm = aPresShell->GetViewManager();
  if (!vm) {
    return;
  }

  nsIScrollableView* scrollableView = nsnull;
  vm->GetRootScrollableView(&scrollableView);
  if (!scrollableView) {
    return;
  }

  scrollableView->AddScrollPositionListener(this);

  // Attach selection listener
  nsCOMPtr<nsISelectionPrivate> selPrivate =
    do_QueryInterface(mFocusedDocSelection);

  if (selPrivate) {
    selPrivate->AddSelectionListener(this);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2335 of file nsTypeAheadFind.cpp.

{
  nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
  GetChromeEventHandler(aDOMWin, getter_AddRefs(chromeEventHandler));
  if (!chromeEventHandler) {
    return;
  }

  // Use capturing, otherwise the normal find next will get activated when ours should
  nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(chromeEventHandler));
  nsCOMPtr<nsIDOMEventGroup> systemGroup;
  receiver->GetSystemEventGroup(getter_AddRefs(systemGroup));
  nsCOMPtr<nsIDOM3EventTarget> target(do_QueryInterface(receiver));

  target->AddGroupedEventListener(NS_LITERAL_STRING("keypress"),
                                  NS_STATIC_CAST(nsIDOMKeyListener*, this),
                                  PR_FALSE, systemGroup);

  // Attach menu listeners, this will help us ignore keystrokes meant for menus
  nsIDOMEventListener *genericEventListener = 
    NS_STATIC_CAST(nsIDOMEventListener*, NS_STATIC_CAST(nsIDOMKeyListener*, this));

  chromeEventHandler->AddEventListener(NS_LITERAL_STRING("popupshown"), 
                                       genericEventListener, 
                                       PR_TRUE);

  chromeEventHandler->AddEventListener(NS_LITERAL_STRING("popuphidden"), 
                                        genericEventListener, 
                                       PR_TRUE);

  chromeEventHandler->AddEventListener(NS_LITERAL_STRING("DOMMenuBarActive"), 
                                       genericEventListener, 
                                       PR_TRUE);
  
  chromeEventHandler->AddEventListener(NS_LITERAL_STRING("DOMMenuBarInactive"), 
                                       genericEventListener, 
                                       PR_TRUE);

  chromeEventHandler->AddEventListener(NS_LITERAL_STRING("unload"), 
                                       genericEventListener, 
                                       PR_TRUE);

  // Add DOM Text listener for IME text events
  nsCOMPtr<nsIDOMEventReceiver> chromeEventReceiver =
    do_QueryInterface(chromeEventHandler);
  chromeEventReceiver->AddEventListenerByIID(NS_STATIC_CAST(nsIDOMTextListener*, this), 
    NS_GET_IID(nsIDOMTextListener));
  chromeEventReceiver->AddEventListenerByIID(NS_STATIC_CAST(nsIDOMCompositionListener*, this), 
    NS_GET_IID(nsIDOMCompositionListener));
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 951 of file nsTypeAheadFind.cpp.

{
  if (mRepeatingMode != eRepeatingNone)
    mTypeAheadBuffer.Truncate();  

  // These will be initialized to their true values after
  // the first character is typed
  mCaretBrowsingOn = PR_FALSE;
  mLiteralTextSearchOnly = PR_FALSE;
  mDontTryExactMatch = PR_FALSE;
  mStartFindRange = nsnull;
  mAllTheSameChar = PR_TRUE; // Until at least 2 different chars are typed

  mSelectionController = nsnull;

  return NS_OK;
}

Manually cancel type ahead find mode.

void nsTypeAheadFind::DisplayStatus ( PRBool  aSuccess,
nsIContent aFocusedContent,
PRBool  aClearStatus,
const PRUnichar aText = nsnull 
) [protected]

Definition at line 2719 of file nsTypeAheadFind.cpp.

{
  // pres shell -> pres context -> container -> tree item ->
  // tree owner -> browser chrome

  nsCOMPtr<nsIPresShell> presShell(GetPresShell());
  if (!presShell) {
    return;
  }

  nsPresContext *presContext = presShell->GetPresContext();
  if (!presContext) {
    return;
  }

  nsCOMPtr<nsISupports> pcContainer = presContext->GetContainer();
  nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(pcContainer));
  if (!treeItem) {
    return;
  }

  nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
  treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
  if (!treeOwner) {
    return;
  }

  nsCOMPtr<nsIWebBrowserChrome> browserChrome(do_GetInterface(treeOwner));
  if (!browserChrome) {
    return;
  }

  nsAutoString statusString;
  if (aText) 
    statusString = aText;
  else {
    if (aClearStatus) {
      GetTranslatedString(NS_LITERAL_STRING("stopfind"), statusString);
    } else if (aSuccess && mTypeAheadBuffer.IsEmpty()) {
      // When find has been started manually
      // but no characters have been typed yet
      nsAutoString key;

      if (mLinksOnly) {
        key.AssignLiteral("startlinkfind");
      } else {
        key.AssignLiteral("starttextfind");
      }
      GetTranslatedString(key, statusString);
    } else {
      nsAutoString key;

      if (mLinksOnly) {
        key.AssignLiteral("link");
      } else {
        key.AssignLiteral("text");
      }

      if (!aSuccess) {
        key.AppendLiteral("not");
      }

      key.AppendLiteral("found");

      if (NS_SUCCEEDED(GetTranslatedString(key, statusString))) {
        if (mRepeatingMode == eRepeatingChar || 
            mRepeatingMode == eRepeatingCharReverse) {
          statusString += mTypeAheadBuffer.First();
        }
        else {
          statusString += mTypeAheadBuffer;
        }

        nsAutoString closeQuoteString, urlString;
        GetTranslatedString(NS_LITERAL_STRING("closequote"), closeQuoteString);
        statusString += closeQuoteString;

        if (mRepeatingMode != eRepeatingNone) {
          if (mRepeatingMode == eRepeatingChar) {
            key.AssignLiteral("repeated");
          }
          else if (mRepeatingMode == eRepeatingForward) {
            key.AssignLiteral("nextmatch");
          }
          else {
            key.AssignLiteral("prevmatch");
          }
          nsAutoString repeatedModeString;
          GetTranslatedString(key, repeatedModeString);
          statusString += NS_LITERAL_STRING(" ") + repeatedModeString;
        }

        nsCOMPtr<nsIDOMNode> focusedNode(do_QueryInterface(aFocusedContent));
        if (focusedNode) {
          presShell->GetLinkLocation(focusedNode, urlString);
        }

        if (!urlString.IsEmpty()) {   // Add URL in parenthesis
          nsAutoString openParenString, closeParenString;
          GetTranslatedString(NS_LITERAL_STRING("openparen"), openParenString);
          GetTranslatedString(NS_LITERAL_STRING("closeparen"), closeParenString);
          statusString += NS_LITERAL_STRING("   ") + openParenString
                          + urlString + closeParenString;
        }
      }
    }
  }

  browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_LINK,
                           PromiseFlatString(statusString).get());
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned short nsITypeAheadFind::find ( in AString  aSearchString,
in boolean  aLinksOnly 
) [inherited]
PRBool nsTypeAheadFind::FindFieldHasFocus ( nsPresContext aPresContext) [protected]

Definition at line 1159 of file nsTypeAheadFind.cpp.

{
  NS_ENSURE_ARG_POINTER(aPresContext);

  nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
  nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(container);
  if (!window) {
    return PR_FALSE;
  }

  nsIFocusController* focusController = window->GetRootFocusController();
  if (!focusController) {
    return PR_FALSE;
  }

  nsCOMPtr<nsIDOMElement> focusedElement;
  focusController->GetFocusedElement(getter_AddRefs(focusedElement));
  nsCOMPtr<nsIContent> content = do_QueryInterface(focusedElement);
  if (!content) {
    return PR_FALSE;
  }

  nsCOMPtr<nsIDOMElement> boundElement =
    do_QueryInterface(content->GetBindingParent());
  if (!boundElement) {
    return PR_FALSE;
  }

  nsAutoString idStr;
  return (NS_SUCCEEDED(boundElement->GetAttribute(NS_LITERAL_STRING("id"),
                                                  idStr)) &&
          idStr.EqualsLiteral("find-field"));
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsTypeAheadFind::FindInternal ( PRBool  aFindBackwards,
PRUint16 aResult 
) [protected]

Definition at line 924 of file nsTypeAheadFind.cpp.

{
  *aResult = FIND_NOTFOUND;

  if (mTypeAheadBuffer.IsEmpty())
    return NS_OK;

  PRBool repeatingSameChar = PR_FALSE;

  if (mRepeatingMode == eRepeatingChar || 
      mRepeatingMode == eRepeatingCharReverse) {
    mRepeatingMode = aFindBackwards? eRepeatingCharReverse: eRepeatingChar;
    repeatingSameChar = PR_TRUE;
  }
  else {
    mRepeatingMode = aFindBackwards? eRepeatingReverse: eRepeatingForward;
  }
  mLiteralTextSearchOnly = PR_TRUE;

  if (NS_FAILED(FindItNow(nsnull, repeatingSameChar, mLinksOnly, PR_FALSE,
                          !aFindBackwards, aResult)))
    mRepeatingMode = eRepeatingNone;

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsTypeAheadFind::FindItNow ( nsIPresShell aPresShell,
PRBool  aIsRepeatingSameChar,
PRBool  aIsLinksOnly,
PRBool  aIsFirstVisiblePreferred,
PRBool  aFindNext,
PRUint16 aResult 
) [protected]

Definition at line 317 of file nsTypeAheadFind.cpp.

{
  *aResult = FIND_NOTFOUND;
  mFoundLink = nsnull;
  mFoundEditable = nsnull;
  mCurrentWindow = nsnull;
  nsCOMPtr<nsIPresShell> startingPresShell (GetPresShell());
  if (!startingPresShell) {    
    nsCOMPtr<nsIDocShell> ds = do_QueryReferent(mDocShell);
    NS_ENSURE_TRUE(ds, NS_ERROR_FAILURE);

    ds->GetPresShell(getter_AddRefs(startingPresShell));
    mPresShell = do_GetWeakReference(startingPresShell);    
  }  

  nsCOMPtr<nsIPresShell> presShell(aPresShell);

  if (!presShell) {
    presShell = startingPresShell;  // this is the current document

    if (!presShell)
      return NS_ERROR_FAILURE;
  }

  nsRefPtr<nsPresContext> presContext = presShell->GetPresContext();

  if (!presContext)
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsISelection> selection;
  nsCOMPtr<nsISelectionController> selectionController = 
    do_QueryReferent(mSelectionController);
  if (!selectionController) {
    GetSelection(presShell, getter_AddRefs(selectionController),
                 getter_AddRefs(selection)); // cache for reuse
    mSelectionController = do_GetWeakReference(selectionController);
  } else {
    selectionController->GetSelection(
      nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
  }
 
  nsCOMPtr<nsISupports> startingContainer = presContext->GetContainer();
  nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(startingContainer));
  NS_ASSERTION(treeItem, "Bug 175321 Crashes with Type Ahead Find [@ nsTypeAheadFind::FindItNow]");
  if (!treeItem)
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIDocShellTreeItem> rootContentTreeItem;
  nsCOMPtr<nsIDocShell> currentDocShell;
  nsCOMPtr<nsIDocShell> startingDocShell(do_QueryInterface(startingContainer));

  treeItem->GetSameTypeRootTreeItem(getter_AddRefs(rootContentTreeItem));
  nsCOMPtr<nsIDocShell> rootContentDocShell =
    do_QueryInterface(rootContentTreeItem);

  if (!rootContentDocShell)
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsISimpleEnumerator> docShellEnumerator;
  rootContentDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeContent,
                                             nsIDocShell::ENUMERATE_FORWARDS,
                                             getter_AddRefs(docShellEnumerator));

  // Default: can start at the current document
  nsCOMPtr<nsISupports> currentContainer = startingContainer =
    do_QueryInterface(rootContentDocShell);

  // Iterate up to current shell, if there's more than 1 that we're
  // dealing with
  PRBool hasMoreDocShells;

  while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMoreDocShells)) && hasMoreDocShells) {
    docShellEnumerator->GetNext(getter_AddRefs(currentContainer));
    currentDocShell = do_QueryInterface(currentContainer);
    if (!currentDocShell || currentDocShell == startingDocShell || aIsFirstVisiblePreferred)
      break;    
  }

  // ------------ Get ranges ready ----------------
  nsCOMPtr<nsIDOMRange> returnRange;
  nsCOMPtr<nsIPresShell> focusedPS;
  if (NS_FAILED(GetSearchContainers(currentContainer,
                                    (!aIsFirstVisiblePreferred ||
                                     mStartFindRange) ?
                                    selectionController.get() : nsnull,
                                    aIsRepeatingSameChar,
                                    aIsFirstVisiblePreferred, 
                                    getter_AddRefs(presShell),
                                    getter_AddRefs(presContext)))) {
    return NS_ERROR_FAILURE;
  }

  PRInt16 rangeCompareResult = 0;
  mStartPointRange->CompareBoundaryPoints(nsIDOMRange::START_TO_START, mSearchRange, &rangeCompareResult);
  // No need to wrap find in doc if starting at beginning
  PRBool hasWrapped = (rangeCompareResult < 0);

  nsAutoString findBuffer;
  if (aIsRepeatingSameChar)
    findBuffer = mTypeAheadBuffer.First();
  else
    findBuffer = PromiseFlatString(mTypeAheadBuffer);

  if (findBuffer.IsEmpty())
    return NS_ERROR_FAILURE;

  mFind->SetFindBackwards(mRepeatingMode == eRepeatingCharReverse || mRepeatingMode == eRepeatingReverse);

  while (PR_TRUE) {    // ----- Outer while loop: go through all docs -----
    while (PR_TRUE) {  // === Inner while loop: go through a single doc ===
      mFind->Find(findBuffer.get(), mSearchRange, mStartPointRange,
                  mEndPointRange, getter_AddRefs(returnRange));            
      
      if (!returnRange)
        break;  // Nothing found in this doc, go to outer loop (try next doc)

      // ------- Test resulting found range for success conditions ------
      PRBool isInsideLink = PR_FALSE, isStartingLink = PR_FALSE;

      if (aIsLinksOnly) {
        // Don't check if inside link when searching all text
        RangeStartsInsideLink(returnRange, presShell, &isInsideLink,
                              &isStartingLink);
      }

      PRBool usesIndependentSelection;
      if (!IsRangeVisible(presShell, presContext, returnRange,
                          aIsFirstVisiblePreferred, PR_FALSE,
                          getter_AddRefs(mStartPointRange), 
                          &usesIndependentSelection) ||
          (aIsRepeatingSameChar && !isStartingLink) ||
          (aIsLinksOnly && !isInsideLink) ||
          (mStartLinksOnlyPref && aIsLinksOnly && !isStartingLink)) {
        // ------ Failure ------
        // Start find again from here
        returnRange->CloneRange(getter_AddRefs(mStartPointRange));

        // Collapse to end
        mStartPointRange->Collapse(mRepeatingMode == eRepeatingReverse || mRepeatingMode == eRepeatingCharReverse);

        continue;
      }

      // ------ Success! -------
      // Hide old selection (new one may be on a different controller)
      if (selection) {
        selection->CollapseToStart();
        SetSelectionModeAndRepaint(nsISelectionController::SELECTION_ON);
      }

      // Make sure new document is selected
      if (presShell != startingPresShell) {
        // We are in a new document (because of frames/iframes)
        mPresShell = do_GetWeakReference(presShell);
      }

      if (usesIndependentSelection) {
        // We may be inside an editable element, and therefore the selection
        // may be controlled by a different selection controller.  Walk up the
        // chain of parent nodes to see if we find one.
        nsCOMPtr<nsIDOMNode> node;
        returnRange->GetStartContainer(getter_AddRefs(node));
        while (node) {
          nsCOMPtr<nsIDOMNSEditableElement> editable = do_QueryInterface(node);
          if (editable) {
            // Inside an editable element.  Get the correct selection 
            // controller and selection.
            nsCOMPtr<nsIEditor> editor;
            editable->GetEditor(getter_AddRefs(editor));
            NS_ASSERTION(editor, "Editable element has no editor!");
            if (!editor) {
              break;
            }
            editor->GetSelectionController(
              getter_AddRefs(selectionController));
            if (selectionController) {
              selectionController->GetSelection(
                nsISelectionController::SELECTION_NORMAL, 
                getter_AddRefs(selection));
            }
            mFoundEditable = do_QueryInterface(node);

            // Check if find field is focused, if so do nothing
            if (FindFieldHasFocus(presContext)) {
              break;
            }

            // Otherwise move focus/caret to editable element
            nsCOMPtr<nsIContent> content = do_QueryInterface(mFoundEditable);
            if (content) {
              content->SetFocus(presContext);
              presContext->EventStateManager()->MoveCaretToFocus();
            }
            break;
          }
          nsIDOMNode* tmp = node;
          tmp->GetParentNode(getter_AddRefs(node));
        }

        // If we reach here without setting mFoundEditable, then something
        // besides editable elements can cause us to have an independent
        // selection controller.  I don't know whether this is possible.
        // Currently, we simply fall back to grabbing the document's selection
        // controller in this case.  Perhaps we should reject this find match
        // and search again.
        NS_ASSERTION(mFoundEditable, "Independent selection controller on "
                     "non-editable element!");
      }

      if (!mFoundEditable) {
        // Not using a separate selection controller, so just get the
        // document's controller and selection.
        GetSelection(presShell, getter_AddRefs(selectionController), 
                     getter_AddRefs(selection));
      }
      mSelectionController = do_GetWeakReference(selectionController);

      // Select the found text
      if (selection) {
        selection->RemoveAllRanges();
        selection->AddRange(returnRange);
      }

      if (!mFoundEditable) {
        currentDocShell->SetHasFocus(PR_TRUE);  // What does this do?

        // Keep track of whether we've found a link, so we can focus it, jump
        // to its target, etc.
        nsIEventStateManager *esm = presContext->EventStateManager();
        PRBool isSelectionWithFocus;
        esm->MoveFocusToCaret(PR_TRUE, &isSelectionWithFocus);
        if (isSelectionWithFocus) {
          nsCOMPtr<nsIContent> lastFocusedContent;
          esm->GetLastFocusedContent(getter_AddRefs(lastFocusedContent));
          nsCOMPtr<nsIDOMElement>
            lastFocusedElement(do_QueryInterface(lastFocusedContent));
          mFoundLink = lastFocusedElement;
        }
      }

      // Change selection color to ATTENTION and scroll to it.  Careful: we
      // must wait until after we goof with focus above before changing to
      // ATTENTION, or when we MoveFocusToCaret() and the selection is not on a
      // link, we'll blur, which will lose the ATTENTION.
      if (selectionController) {
        SetSelectionModeAndRepaint(nsISelectionController::SELECTION_ATTENTION);
        selectionController->ScrollSelectionIntoView(
          nsISelectionController::SELECTION_NORMAL, 
          nsISelectionController::SELECTION_FOCUS_REGION, PR_TRUE);
      }

      nsCOMPtr<nsIDocument> doc =
        do_QueryInterface(presShell->GetDocument());
      NS_ASSERTION(doc, "Wow, presShell doesn't have document!");
      mCurrentWindow = do_QueryInterface(doc->GetScriptGlobalObject());

      if (hasWrapped) {
        *aResult = FIND_WRAPPED;
      } else {
        *aResult = FIND_FOUND;
      }

      return NS_OK;
    }

    // ======= end-inner-while (go through a single document) ==========

    // ---------- Nothing found yet, try next document  -------------
    PRBool hasTriedFirstDoc = PR_FALSE;
    do {
      // ==== Second inner loop - get another while  ====
      if (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMoreDocShells))
          && hasMoreDocShells) {
        docShellEnumerator->GetNext(getter_AddRefs(currentContainer));
        NS_ASSERTION(currentContainer, "HasMoreElements lied to us!");
        currentDocShell = do_QueryInterface(currentContainer);

        if (currentDocShell)
          break;
      }
      else if (hasTriedFirstDoc)  // Avoid potential infinite loop
        return NS_ERROR_FAILURE;  // No content doc shells

      // Reached last doc shell, loop around back to first doc shell
      rootContentDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeContent,
                                                 nsIDocShell::ENUMERATE_FORWARDS,
                                                 getter_AddRefs(docShellEnumerator));
      hasTriedFirstDoc = PR_TRUE;      
    } while (docShellEnumerator);  // ==== end second inner while  ===

    PRBool continueLoop = PR_FALSE;
    if (currentDocShell != startingDocShell)
      continueLoop = PR_TRUE;  // Try next document
    else if (!hasWrapped || aIsFirstVisiblePreferred) {
      // Finished searching through docshells:
      // If aFirstVisiblePreferred == PR_TRUE, we may need to go through all
      // docshells twice -once to look for visible matches, the second time
      // for any match
      aIsFirstVisiblePreferred = PR_FALSE;
      hasWrapped = PR_TRUE;
      continueLoop = PR_TRUE; // Go through all docs again
    }

    if (continueLoop) {
      if (NS_FAILED(GetSearchContainers(currentContainer,
                                        nsnull,
                                        aIsRepeatingSameChar,
                                        aIsFirstVisiblePreferred,
                                        getter_AddRefs(presShell),
                                        getter_AddRefs(presContext)))) {
        continue;
      }

      if (mRepeatingMode == eRepeatingCharReverse || mRepeatingMode == eRepeatingReverse) {
        // Reverse mode: swap start and end points, so that we start
        // at end of document and go to beginning
        nsCOMPtr<nsIDOMRange> tempRange;
        mStartPointRange->CloneRange(getter_AddRefs(tempRange));
        mStartPointRange = mEndPointRange;
        mEndPointRange = tempRange;
      }

      continue;
    }

    // ------------- Failed --------------
    break;
  }   // end-outer-while: go through all docs

  return NS_ERROR_FAILURE;
}

Here is the call graph for this function:

nsresult nsTypeAheadFind::FindItNow ( nsIPresShell aPresShell,
PRBool  aIsRepeatingSameChar,
PRBool  aIsLinksOnly,
PRBool  aIsFirstVisiblePreferred 
) [protected]

Definition at line 1222 of file nsTypeAheadFind.cpp.

{
  nsCOMPtr<nsIPresShell> presShell(aPresShell);
  nsCOMPtr<nsIPresShell> startingPresShell = GetPresShell();

  if (!presShell) {
    presShell = startingPresShell;  // this is the current document

    if (!presShell) {
      return NS_ERROR_FAILURE;
    }
  }

  nsCOMPtr<nsPresContext> presContext = presShell->GetPresContext();
  if (!presContext) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsISupports> startingContainer = presContext->GetContainer();
  nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(startingContainer));
  NS_ASSERTION(treeItem, "Bug 175321 Crashes with Type Ahead Find [@ nsTypeAheadFind::FindItNow]");
  if (!treeItem) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIDocShellTreeItem> rootContentTreeItem;
  nsCOMPtr<nsIDocShell> currentDocShell;
  nsCOMPtr<nsIDocShell> startingDocShell(do_QueryInterface(startingContainer));

  treeItem->GetSameTypeRootTreeItem(getter_AddRefs(rootContentTreeItem));
  nsCOMPtr<nsIDocShell> rootContentDocShell =
    do_QueryInterface(rootContentTreeItem);

  if (!rootContentDocShell) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsISimpleEnumerator> docShellEnumerator;
  rootContentDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeContent,
                                             nsIDocShell::ENUMERATE_FORWARDS,
                                             getter_AddRefs(docShellEnumerator));

  // Default: can start at the current document
  nsCOMPtr<nsISupports> currentContainer = startingContainer =
    do_QueryInterface(rootContentDocShell);

  // Iterate up to current shell, if there's more than 1 that we're
  // dealing with
  PRBool hasMoreDocShells;

  while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMoreDocShells))
         && hasMoreDocShells) {
    docShellEnumerator->GetNext(getter_AddRefs(currentContainer));
    currentDocShell = do_QueryInterface(currentContainer);
    if (!currentDocShell || currentDocShell == startingDocShell ||
        aIsFirstVisiblePreferred) {
      break;
    }
  }

  // ------------ Get ranges ready ----------------
  nsCOMPtr<nsIDOMRange> returnRange;
  if (NS_FAILED(GetSearchContainers(currentContainer, aIsRepeatingSameChar,
                                    aIsFirstVisiblePreferred, 
                                    !aIsFirstVisiblePreferred || mStartFindRange,
                                    getter_AddRefs(presShell),
                                    getter_AddRefs(presContext)))) {
    return NS_ERROR_FAILURE;
  }

  PRInt16 rangeCompareResult = 0;
  mStartPointRange->CompareBoundaryPoints(nsIDOMRange::START_TO_START,
                                          mSearchRange, &rangeCompareResult);
  // No need to wrap find in doc if starting at beginning
  PRBool hasWrapped = (rangeCompareResult <= 0);

  nsAutoString findBuffer;
  if (aIsRepeatingSameChar) {
    findBuffer = mTypeAheadBuffer.First();
  } else {
    findBuffer = PromiseFlatString(mTypeAheadBuffer);
  }

  if (findBuffer.IsEmpty())
    return NS_ERROR_FAILURE;

  mFind->SetFindBackwards(mRepeatingMode == eRepeatingCharReverse ||
    mRepeatingMode == eRepeatingReverse);

  while (PR_TRUE) {    // ----- Outer while loop: go through all docs -----
    while (PR_TRUE) {  // === Inner while loop: go through a single doc ===
      mFind->Find(findBuffer.get(), mSearchRange, mStartPointRange,
                  mEndPointRange, getter_AddRefs(returnRange));
      if (!returnRange) {
        break;  // Nothing found in this doc, go to outer loop (try next doc)
      }

      // ------- Test resulting found range for success conditions ------
      PRBool isInsideLink = PR_FALSE, isStartingLink = PR_FALSE;

      if (aIsLinksOnly) {
        // Don't check if inside link when searching all text

        RangeStartsInsideLink(returnRange, presShell, &isInsideLink,
                              &isStartingLink);
      }

      if (!IsRangeVisible(presShell, presContext, returnRange,
                          aIsFirstVisiblePreferred, PR_FALSE,
                          getter_AddRefs(mStartPointRange)) ||
          (aIsRepeatingSameChar && !isStartingLink) ||
          (aIsLinksOnly && !isInsideLink) ||
          (mStartLinksOnlyPref && aIsLinksOnly && !isStartingLink)) {
        // ------ Failure ------
        // Start find again from here
        returnRange->CloneRange(getter_AddRefs(mStartPointRange));

        // Collapse to end
        mStartPointRange->Collapse(mRepeatingMode == eRepeatingReverse || 
          mRepeatingMode == eRepeatingCharReverse);

        continue;
      }

      // ------ Success! -------
      // Make sure new document is selected
      if (presShell != startingPresShell) {
        // We are in a new document (because of frames/iframes)
        mFocusedDocSelection->CollapseToStart(); // Hide old doc's selection
        SetSelectionLook(startingPresShell, PR_FALSE, PR_FALSE); // hide caret

        nsIDocument *doc = presShell->GetDocument();
        if (!doc) {
          return NS_ERROR_FAILURE;
        }
        mFocusedWeakShell = do_GetWeakReference(presShell);

        // Get selection controller and selection for new frame/iframe
        GetSelection(presShell, getter_AddRefs(mFocusedDocSelCon), 
                     getter_AddRefs(mFocusedDocSelection));
      }
 
     if (!mFocusedDocSelection || !mFocusedDocSelCon) {
        // Apparently these can go away even though presshell/prescontext exist
        return NS_ERROR_FAILURE;
      }

      // Select the found text and focus it
      mFocusedDocSelection->RemoveAllRanges();
      mFocusedDocSelection->AddRange(returnRange);
      mFocusedDocSelCon->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL,
                                                 nsISelectionController::SELECTION_FOCUS_REGION, PR_TRUE);
      SetSelectionLook(presShell, PR_TRUE, mRepeatingMode != eRepeatingForward 
                                           && mRepeatingMode != eRepeatingReverse);

      nsIEventStateManager *esm = presContext->EventStateManager();

      PRBool isSelectionWithFocus;
      esm->SetContentState(nsnull, NS_EVENT_STATE_FOCUS); // Start off focusing doc
      esm->MoveFocusToCaret(PR_TRUE, &isSelectionWithFocus);

      nsCOMPtr<nsIContent> focusedContent;
      esm->GetFocusedContent(getter_AddRefs(focusedContent));

      DisplayStatus(PR_TRUE, focusedContent, PR_FALSE);

      mBadKeysSinceMatch = 0;

      return NS_OK;
    }

    // ======= end-inner-while (go through a single document) ==========

    // ---------- Nothing found yet, try next document  -------------
    PRBool hasTriedFirstDoc = PR_FALSE;
    do {
      // ==== Second inner loop - get another while  ====
      if (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMoreDocShells))
          && hasMoreDocShells) {
        docShellEnumerator->GetNext(getter_AddRefs(currentContainer));
        NS_ASSERTION(currentContainer, "HasMoreElements lied to us!");
        currentDocShell = do_QueryInterface(currentContainer);

        if (currentDocShell) {
          break;
        }
      }
      else if (hasTriedFirstDoc) {  // Avoid potential infinite loop
        return NS_ERROR_FAILURE;  // No content doc shells
      }

      // Reached last doc shell, loop around back to first doc shell
      rootContentDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeContent,
                                                 nsIDocShell::ENUMERATE_FORWARDS,
                                                 getter_AddRefs(docShellEnumerator));
      hasTriedFirstDoc = PR_TRUE;
    } while (docShellEnumerator);  // ==== end second inner while  ===

    PRBool continueLoop = PR_FALSE;
    if (currentDocShell != startingDocShell) {
      continueLoop = PR_TRUE;  // Try next document
    }
    else if (!hasWrapped || aIsFirstVisiblePreferred) {
      // Finished searching through docshells:
      // If aFirstVisiblePreferred == PR_TRUE, we may need to go through all
      // docshells twice -once to look for visible matches, the second time
      // for any match
      aIsFirstVisiblePreferred = PR_FALSE;
      hasWrapped = PR_TRUE;
      continueLoop = PR_TRUE; // Go through all docs again
    }

    if (continueLoop) {
      if (NS_FAILED(GetSearchContainers(currentContainer,
                                        aIsRepeatingSameChar,
                                        aIsFirstVisiblePreferred, PR_FALSE,
                                        getter_AddRefs(presShell),
                                        getter_AddRefs(presContext)))) {
        return NS_ERROR_FAILURE;
      }

      if (mRepeatingMode == eRepeatingCharReverse ||
          mRepeatingMode == eRepeatingReverse) {
        // Reverse mode:
        // swap start and end points, so that we start
        // at end of document and go to beginning
        nsCOMPtr<nsIDOMRange> tempRange;
        mStartPointRange->CloneRange(getter_AddRefs(tempRange));
        mStartPointRange = mEndPointRange;
        mEndPointRange = tempRange;
      }

      continue;
    }

    // ------------- Failed --------------
    break;
  }   // end-outer-while: go through all docs

  return NS_ERROR_FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned short nsITypeAheadFind::findNext ( ) [inherited]
void nsITypeAheadFind::findNext ( in boolean  aReverse,
in nsISupportsInterfacePointer  aCallerWindowSupports 
) [inherited]

Find next recurrence if typeaheadfind was the last used find, as opposed to regular find.

Returns false in nsISupportsPRBool if we don't handle the request.

unsigned short nsITypeAheadFind::findPrevious ( ) [inherited]
void nsTypeAheadFind::GetChromeEventHandler ( nsIDOMWindow aDOMWin,
nsIDOMEventTarget **  aChromeTarget 
) [protected]

Definition at line 2388 of file nsTypeAheadFind.cpp.

{
  nsCOMPtr<nsPIDOMWindow> privateDOMWindow(do_QueryInterface(aDOMWin));
  nsIChromeEventHandler *chromeEventHandler = nsnull;
  if (privateDOMWindow) {
    chromeEventHandler = privateDOMWindow->GetChromeEventHandler();
  }

  nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(chromeEventHandler));

  *aChromeTarget = target;
  NS_IF_ADDREF(*aChromeTarget);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 221 of file nsTypeAheadFind.cpp.

{
  if (!sInstance) {
    sInstance = new nsTypeAheadFind();
    if (!sInstance)
      return nsnull;

    NS_ADDREF(sInstance);  // addref for sInstance global

    if (NS_FAILED(sInstance->Init())) {
      NS_RELEASE(sInstance);

      return nsnull;
    }
  }

  NS_ADDREF(sInstance);   // addref for the getter

  return sInstance;
}

Here is the call graph for this function:

nsresult nsTypeAheadFind::GetSearchContainers ( nsISupports *  aContainer,
nsISelectionController aSelectionController,
PRBool  aIsRepeatingSameChar,
PRBool  aIsFirstVisiblePreferred,
nsIPresShell **  aPresShell,
nsPresContext **  aPresContext 
) [protected]

Definition at line 699 of file nsTypeAheadFind.cpp.

{
  NS_ENSURE_ARG_POINTER(aContainer);
  NS_ENSURE_ARG_POINTER(aPresShell);
  NS_ENSURE_ARG_POINTER(aPresContext);

  *aPresShell = nsnull;
  *aPresContext = nsnull;

  nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
  if (!docShell)
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIPresShell> presShell;
  docShell->GetPresShell(getter_AddRefs(presShell));

  nsRefPtr<nsPresContext> presContext;
  docShell->GetPresContext(getter_AddRefs(presContext));

  if (!presShell || !presContext)
    return NS_ERROR_FAILURE;

  nsIDocument* doc = presShell->GetDocument();

  if (!doc)
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIContent> rootContent;
  nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(doc));
  if (htmlDoc) {
    nsCOMPtr<nsIDOMHTMLElement> bodyEl;
    htmlDoc->GetBody(getter_AddRefs(bodyEl));
    rootContent = do_QueryInterface(bodyEl);
  }

  if (!rootContent)
    rootContent = doc->GetRootContent();
 
  nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootContent));

  if (!rootNode)
    return NS_ERROR_FAILURE;

  PRUint32 childCount = rootContent->GetChildCount();

  mSearchRange->SelectNodeContents(rootNode);

  mEndPointRange->SetEnd(rootNode, childCount);
  mEndPointRange->Collapse(PR_FALSE); // collapse to end

  // Consider current selection as null if
  // it's not in the currently focused document
  nsCOMPtr<nsIDOMRange> currentSelectionRange;
  nsCOMPtr<nsIPresShell> selectionPresShell = GetPresShell();
  if (aSelectionController && selectionPresShell && selectionPresShell == presShell) {
    nsCOMPtr<nsISelection> selection;
    aSelectionController->GetSelection(
      nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
    if (selection)
      selection->GetRangeAt(0, getter_AddRefs(currentSelectionRange));
  }

  if (!currentSelectionRange) {
    // Ensure visible range, move forward if necessary
    // This uses ignores the return value, but usese the side effect of
    // IsRangeVisible. It returns the first visible range after searchRange
    IsRangeVisible(presShell, presContext, mSearchRange, 
                   aIsFirstVisiblePreferred, PR_TRUE, 
                   getter_AddRefs(mStartPointRange), nsnull);
  }
  else {
    PRInt32 startOffset;
    nsCOMPtr<nsIDOMNode> startNode;
    if ((aIsRepeatingSameChar && mRepeatingMode != eRepeatingCharReverse) || 
        mRepeatingMode == eRepeatingForward) {
      currentSelectionRange->GetEndContainer(getter_AddRefs(startNode));
      currentSelectionRange->GetEndOffset(&startOffset);
    }
    else {
      currentSelectionRange->GetStartContainer(getter_AddRefs(startNode));
      currentSelectionRange->GetStartOffset(&startOffset);
    }
    if (!startNode)
      startNode = rootNode;    

    // We need to set the start point this way, other methods haven't worked
    mStartPointRange->SelectNode(startNode);
    mStartPointRange->SetStart(startNode, startOffset);
  }

  mStartPointRange->Collapse(PR_TRUE); // collapse to start

  *aPresShell = presShell;
  NS_ADDREF(*aPresShell);

  *aPresContext = presContext;
  NS_ADDREF(*aPresContext);

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsTypeAheadFind::GetSearchContainers ( nsISupports *  aContainer,
PRBool  aIsRepeatingSameChar,
PRBool  aIsFirstVisiblePreferred,
PRBool  aCanUseDocSelection,
nsIPresShell **  aPresShell,
nsPresContext **  aPresContext 
) [protected]

Definition at line 1468 of file nsTypeAheadFind.cpp.

{
  NS_ENSURE_ARG_POINTER(aContainer);
  NS_ENSURE_ARG_POINTER(aPresShell);
  NS_ENSURE_ARG_POINTER(aPresContext);

  *aPresShell = nsnull;
  *aPresContext = nsnull;

  nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
  if (!docShell) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsPresContext> presContext;
  nsCOMPtr<nsIPresShell> presShell;

  docShell->GetPresShell(getter_AddRefs(presShell));
  docShell->GetPresContext(getter_AddRefs(presContext));

  if (!presShell || !presContext) {
    return NS_ERROR_FAILURE;
  }

  nsIDocument *doc = presShell->GetDocument();
  if (!doc) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIContent> rootContent;
  nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(doc));
  if (htmlDoc) {
    nsCOMPtr<nsIDOMHTMLElement> bodyEl;
    htmlDoc->GetBody(getter_AddRefs(bodyEl));
    rootContent = do_QueryInterface(bodyEl);
  }
  if (!rootContent) {
    rootContent = doc->GetRootContent();
  }
  nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootContent));

  if (!rootNode) {
    return NS_ERROR_FAILURE;
  }

  PRUint32 childCount = rootContent->GetChildCount();

  mSearchRange->SelectNodeContents(rootNode);

  mEndPointRange->SetEnd(rootNode, childCount);
  mEndPointRange->Collapse(PR_FALSE); // collapse to end

  // Consider current selection as null if
  // it's not in the currently focused document
  nsCOMPtr<nsIDOMRange> currentSelectionRange;
  nsCOMPtr<nsIPresShell> selectionPresShell = GetPresShell();

  if (aCanUseDocSelection && selectionPresShell == presShell && mFocusedDocSelection) {
    mFocusedDocSelection->GetRangeAt(0, getter_AddRefs(currentSelectionRange));
  }

  if (!currentSelectionRange) {
    // Ensure visible range, move forward if necessary
    // This uses ignores the return value, but usese the side effect of
    // IsRangeVisible. It returns the first visible range after searchRange
    IsRangeVisible(presShell, presContext, mSearchRange, 
                   aIsFirstVisiblePreferred, PR_TRUE, 
                   getter_AddRefs(mStartPointRange));
  }
  else {
    PRInt32 startOffset;
    nsCOMPtr<nsIDOMNode> startNode;
    if ((aIsRepeatingSameChar && mRepeatingMode != eRepeatingCharReverse) || 
        mRepeatingMode == eRepeatingForward) {
      currentSelectionRange->GetEndContainer(getter_AddRefs(startNode));
      currentSelectionRange->GetEndOffset(&startOffset);
    }
    else {
      currentSelectionRange->GetStartContainer(getter_AddRefs(startNode));
      currentSelectionRange->GetStartOffset(&startOffset);
    }
    if (!startNode) {
      startNode = rootNode;
    }

    // We need to set the start point this way, other methods haven't worked
    mStartPointRange->SelectNode(startNode);
    mStartPointRange->SetStart(startNode, startOffset);
  }

  mStartPointRange->Collapse(PR_TRUE); // collapse to start

  *aPresShell = presShell;
  NS_ADDREF(*aPresShell);

  *aPresContext = presContext;
  NS_ADDREF(*aPresContext);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTypeAheadFind::GetSelection ( nsIPresShell aPresShell,
nsISelectionController **  aSelCon,
nsISelection **  aDomSel 
) [protected]
void nsTypeAheadFind::GetSelection ( nsIPresShell aPresShell,
nsISelectionController **  aSelCon,
nsISelection **  aDomSel 
) [protected]

Definition at line 2525 of file nsTypeAheadFind.cpp.

{
  // if aCurrentNode is nsnull, get selection for document
  *aDOMSel = nsnull;

  nsPresContext *presContext = aPresShell->GetPresContext();

  nsIFrame *frame = aPresShell->GetRootFrame();

  if (presContext && frame) {
    frame->GetSelectionController(presContext, aSelCon);
    if (*aSelCon) {
      (*aSelCon)->GetSelection(nsISelectionController::SELECTION_NORMAL,
                               aDOMSel);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTypeAheadFind::GetStartWindow ( nsIDOMWindow aWindow,
nsIDOMWindow **  aStartWindow 
) [protected]

Definition at line 2089 of file nsTypeAheadFind.cpp.

{
  // Return the root ancestor content window of aWindow

  *aStartWindow = nsnull;
  nsCOMPtr<nsIInterfaceRequestor> ifreq(do_QueryInterface(aWindow));
  NS_ASSERTION(ifreq, "Can't get interface requestor");
  if (!ifreq)
    return;

  nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(ifreq));
  nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(webNav));
  NS_ASSERTION(ifreq, "Can't get doc shell tree item");
  if (!treeItem)
    return;
  
  PRInt32 docShellType;
  treeItem->GetItemType(&docShellType);
  if (docShellType == nsIDocShellTreeItem::typeContent) {
    nsCOMPtr<nsIDocShellTreeItem> rootContentTreeItem;
    treeItem->GetSameTypeRootTreeItem(getter_AddRefs(rootContentTreeItem));
    nsCOMPtr<nsIDOMWindow> domWin(do_GetInterface(rootContentTreeItem));
    *aStartWindow = domWin;
  }
  else {
    *aStartWindow = aWindow;
  }

  NS_IF_ADDREF(*aStartWindow);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsTypeAheadFind::GetTargetIfTypeAheadOkay ( nsIDOMEvent aEvent,
nsIContent **  aTargetContent,
nsIPresShell **  aTargetPresShell 
) [protected]

Definition at line 2442 of file nsTypeAheadFind.cpp.

{
  NS_ENSURE_ARG_POINTER(aEvent);
  NS_ENSURE_ARG_POINTER(aTargetContent);
  NS_ENSURE_ARG_POINTER(aTargetPresShell);

  *aTargetContent = nsnull;
  *aTargetPresShell = nsnull;

  nsCOMPtr<nsIDOMNSEvent> nsEvent(do_QueryInterface(aEvent));
  if (!nsEvent) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIDOMEventTarget> domEventTarget;
  nsEvent->GetOriginalTarget(getter_AddRefs(domEventTarget));

  nsCOMPtr<nsIContent> targetContent(do_QueryInterface(domEventTarget));

  // ---- Exit early if in form controls that can be typed in ---------

  if (!IsTargetContentOkay(targetContent)) {
    if (!mTypeAheadBuffer.IsEmpty()) {
      CancelFind();
    }
    return NS_OK;
  }

  NS_ADDREF(*aTargetContent = targetContent);

  // ---------- Is the keystroke in a new window? -------------------

  nsCOMPtr<nsIDocument> doc = targetContent->GetDocument();
  if (!doc) {
    return NS_OK;
  }

  nsCOMPtr<nsIDOMWindow> domWin(do_QueryInterface(doc->GetScriptGlobalObject()));
  nsCOMPtr<nsIDOMWindow> topContentWin;
  GetStartWindow(domWin, getter_AddRefs(topContentWin));

  // ---------- Get presshell -----------

  nsIPresShell *presShell = doc->GetShellAt(0);
  if (!presShell) {
    return NS_OK;
  }

  nsCOMPtr<nsIPresShell> lastShell(GetPresShell());

  if (lastShell != presShell || topContentWin != mFocusedWindow) {
    GetAutoStart(topContentWin, &mIsFindAllowedInWindow);
    if (mIsFindAllowedInWindow) {
      UseInWindow(topContentWin);
    }
    else {
      CancelFind();
      mFocusedWindow = nsnull;
    }
  }
  if (!mIsFindAllowedInWindow) {
    return NS_OK;
  }

  if (presShell->GetPresContext()->Type() == nsPresContext::eContext_PrintPreview) {
    // Typeaheadfind is not designed to work in print preview.
    // You can't navigate through the links there.
    if (lastShell != presShell) {
      mFocusedWeakShell = do_GetWeakReference(presShell);
      CancelFind();
      DisplayStatus(PR_FALSE, nsnull, PR_TRUE, EmptyString().get());  // Clear status
    }
    return NS_OK;
  }
  
  NS_ADDREF(*aTargetPresShell = presShell);  
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTypeAheadFind::GetTopContentPresShell ( nsIDocShellTreeItem aTreeItem,
nsIPresShell **  aPresShell 
) [protected]

Definition at line 2073 of file nsTypeAheadFind.cpp.

{
  *aPresShell = nsnull;

  nsCOMPtr<nsIDocShellTreeItem> topContentTreeItem;
  aDocShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(topContentTreeItem));
  nsCOMPtr<nsIDocShell> topContentDocShell(do_QueryInterface(topContentTreeItem));

  if (!topContentDocShell)
    return;

  topContentDocShell->GetPresShell(aPresShell);
}

Here is the call graph for this function:

nsresult nsTypeAheadFind::GetTranslatedString ( const nsAString &  aKey,
nsAString &  aStringOut 
) [protected]

Definition at line 2701 of file nsTypeAheadFind.cpp.

{
  nsXPIDLString xsValue;

  if (!mStringBundle ||
    NS_FAILED(mStringBundle->GetStringFromName(PromiseFlatString(aKey).get(),
                                               getter_Copies(xsValue)))) {
    return NS_ERROR_FAILURE;
  }

  aStringOut.Assign(xsValue);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsTypeAheadFind::GetWebBrowserFind ( nsIDocShell aDocShell,
nsIWebBrowserFind **  aWebBrowserFind 
) [protected]
nsresult nsTypeAheadFind::GetWebBrowserFind ( nsIDOMWindow aDOMWin,
nsIWebBrowserFind **  aWebBrowserFind 
) [protected]

Definition at line 2121 of file nsTypeAheadFind.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 866 of file nsTypeAheadFind.cpp.

{
  // Add a printable char to mTypeAheadBuffer, then search for buffer contents

  // ------------ Million keys protection -------------
  if (mBadKeysSinceMatch >= kMaxBadCharsBeforeCancel) {
    // If they're just quickly mashing keys onto the keyboard, stop searching
    // until typeahead find is canceled via timeout or another normal means
    StartTimeout();  // Timeout from last bad key (this one)
    DisplayStatus(PR_FALSE, nsnull, PR_TRUE); // Status message to say find stopped
    return NS_ERROR_FAILURE;
  }

  aChar = ToLowerCase(NS_STATIC_CAST(PRUnichar, aChar));
  PRInt32 bufferLength = mTypeAheadBuffer.Length();

  mIsFirstVisiblePreferred = PR_FALSE;

  // --------- No new chars after find again ----------
  if (mRepeatingMode == eRepeatingForward ||
      mRepeatingMode == eRepeatingReverse) {
    // Once Accel+[shift]+G or [shift]+F3 has been used once,
    // new typing will start a new find
    CancelFind();
    bufferLength = 0;
    mRepeatingMode = eRepeatingNone;
  }
  // --------- New char in repeated char mode ---------
  else if ((mRepeatingMode == eRepeatingChar ||
           mRepeatingMode == eRepeatingCharReverse) && 
           bufferLength > 1 && aChar != mTypeAheadBuffer.First()) {
    // If they repeat the same character and then change, such as aaaab
    // start over with new char as a repeated char find
    mTypeAheadBuffer = aChar;
  }
  // ------- Set repeating mode ---------
  else if (bufferLength > 0) {
    if (mTypeAheadBuffer.First() != aChar) {
      mRepeatingMode = eRepeatingNone;
      mAllTheSameChar = PR_FALSE;
    }
  }

  mTypeAheadBuffer += aChar;    // Add the char!

  // --------- Initialize find if 1st char ----------
  if (bufferLength == 0) {
    if (!mLinksOnlyManuallySet) {
      // Reset links only to default, if not manually set
      // by the user via ' or / keypress at beginning
      mLinksOnly = mLinksOnlyPref;
    }

    mRepeatingMode = eRepeatingNone;

    // If you can see the selection (not collapsed or thru caret browsing),
    // or if already focused on a page element, start there.
    // Otherwise we're going to start at the first visible element
    NS_ENSURE_TRUE(mFocusedDocSelection, NS_ERROR_FAILURE);
    PRBool isSelectionCollapsed;
    mFocusedDocSelection->GetIsCollapsed(&isSelectionCollapsed);

    // If true, we will scan from top left of visible area
    // If false, we will scan from start of selection
    mIsFirstVisiblePreferred = !mCaretBrowsingOn && isSelectionCollapsed;
    if (mIsFirstVisiblePreferred) {
      // Get focused content from esm. If it's null, the document is focused.
      // If not, make sure the selection is in sync with the focus, so we can 
      // start our search from there.
      nsCOMPtr<nsIContent> focusedContent;
      nsCOMPtr<nsIPresShell> presShell(GetPresShell());
      NS_ENSURE_TRUE(presShell, NS_OK);
      nsPresContext *presContext = presShell->GetPresContext();
      NS_ENSURE_TRUE(presContext, NS_OK);

      nsIEventStateManager *esm = presContext->EventStateManager();
      esm->GetFocusedContent(getter_AddRefs(focusedContent));
      if (focusedContent) {
        mIsFindingText = PR_TRUE; // prevent selection listener from calling CancelFind()
        esm->MoveCaretToFocus();
        mIsFindingText = PR_FALSE;
        mIsFirstVisiblePreferred = PR_FALSE;
      }
      else {
        nsCOMPtr<nsISupports> container = presContext->GetContainer();
        nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = 
          do_QueryInterface(container);
        nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
        docShellTreeItem->GetSameTypeParent(getter_AddRefs(parentTreeItem));
        if (parentTreeItem) {
          mIsFirstVisiblePreferred = PR_FALSE; // focused on a frame or iframe
        }
      }
    }
  }

  // ----------- Find the text! ---------------------
  mIsFindingText = PR_TRUE; // prevent selection listener from calling CancelFind()

  nsresult rv = NS_ERROR_FAILURE;

  if (mBadKeysSinceMatch <= 1) {   // Don't even try if the last key was already bad
    if (!mDontTryExactMatch) {
      // Regular find, not repeated char find

      // Prefer to find exact match
      rv = FindItNow(nsnull, PR_FALSE, mLinksOnly, mIsFirstVisiblePreferred);
    }

#ifndef NO_LINK_CYCLE_ON_SAME_CHAR
    if (NS_FAILED(rv) && !mLiteralTextSearchOnly && mAllTheSameChar && 
        mTypeAheadBuffer.Length() > 1) {
      mRepeatingMode = eRepeatingChar;
      mDontTryExactMatch = PR_TRUE;  // Repeated character find mode
      rv = FindItNow(nsnull, PR_TRUE, PR_TRUE, mIsFirstVisiblePreferred);
    }
#endif
  }

  // ---------Handle success or failure ---------------
  mIsFindingText = PR_FALSE;
  if (NS_SUCCEEDED(rv)) {
    mLastBadChar = 0;
    if (mTypeAheadBuffer.Length() == 1) {
      // If first letter, store where the first find succeeded
      // (mStartFindRange)

      mStartFindRange = nsnull;
      nsCOMPtr<nsIDOMRange> startFindRange;
      mFocusedDocSelection->GetRangeAt(0, getter_AddRefs(startFindRange));

      if (startFindRange) {
        startFindRange->CloneRange(getter_AddRefs(mStartFindRange));
      }
    }
  }
  else {
    if (aChar == '/' || aChar == '\'') {
      // Didn't find / or ' -- use that key to start a new text or link find
      return StartNewFind(mFocusedWindow, aChar == '\'');
    }
    PRUint32 length = mTypeAheadBuffer.Length();
    if (mLastBadChar && length >= 1) {
      // We have to do this to put the exact typed string in the status 
      // Otherwise, it will be missing mLastBadChar, which had been removed
      // so that the user could avoid pressing backspace
      nsAutoString lastTwoCharsTyped(mLastBadChar);
      lastTwoCharsTyped += mTypeAheadBuffer.CharAt(length - 1);
      mTypeAheadBuffer.Truncate(length - 1);
      mTypeAheadBuffer += lastTwoCharsTyped;
      ++length;
    }
    DisplayStatus(PR_FALSE, nsnull, PR_FALSE); // Display failure status
    mRepeatingMode = eRepeatingNone;

    ++mBadKeysSinceMatch;

    // Error sound (don't fire when backspace is pressed, they're 
    // trying to correct the mistake!)
    PlayNotFoundSound();

    // Remove bad character from buffer, so we can continue typing from
    // last matched character
    if (length >= 1) {
      mLastBadChar = mTypeAheadBuffer.CharAt(length - 1);
      mTypeAheadBuffer.Truncate(length - 1);
    }
  }

  SaveFind();

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Implements nsIDOMCompositionListener.

Definition at line 1170 of file nsTypeAheadFind.cpp.

{
  // This is called once at the end of an IME composition

  if (!mIsIMETypeAheadActive) {
    return PR_FALSE;
  }

  // -------- Find the composed chars one at a time ---------
  nsReadingIterator<PRUnichar> iter;
  nsReadingIterator<PRUnichar> iterEnd;

  mIMEString.BeginReading(iter);
  mIMEString.EndReading(iterEnd);

  // Handle the characters one at a time
  while (iter != iterEnd) {
    if (NS_FAILED(HandleChar(*iter))) {
      // Character not found, exit loop early
      break;
    }
    ++iter;
  }

  mIMEString.Truncate(); // To be safe, so that find won't happen twice

  return NS_OK;
}

Here is the call graph for this function:

This method is called whenever an event occurs of the type for which the EventListener interface was registered.

Parameters:
evtThe Event contains contextual information about the event. It also contains the stopPropagation and preventDefault methods which are used in determining the event's flow and default action.

Implements nsIDOMCompositionListener.

Definition at line 1215 of file nsTypeAheadFind.cpp.

{
  return NS_OK;
}

Implements nsIDOMCompositionListener.

Definition at line 1201 of file nsTypeAheadFind.cpp.

{
  return NS_OK;
}

Implements nsIDOMCompositionListener.

Definition at line 1208 of file nsTypeAheadFind.cpp.

{
  return NS_OK;
}

Implements nsIDOMCompositionListener.

Definition at line 1148 of file nsTypeAheadFind.cpp.

{
  // This is called once at the start of an IME composition

  mIsIMETypeAheadActive = PR_TRUE;

  if (!mIsTypeAheadOn || mIsMenuBarActive || mIsMenuPopupActive) {
    mIsIMETypeAheadActive = PR_FALSE;
    return NS_OK;
  }

  // Pause the cancellation timer until IME is finished
  // HandleChar() will start it again
  if (mTimer) {
    mTimer->Cancel();
  }

  return NS_OK;
}

Implements nsIDOMTextListener.

Definition at line 1100 of file nsTypeAheadFind.cpp.

{
  // This is called multiple times in the middle of an 
  // IME composition

  if (!mIsIMETypeAheadActive) {
    return NS_OK;
  }

  // ------- Check if Type Ahead can occur here -------------
  // (and if it can, get the target content and document)
  nsCOMPtr<nsIContent> targetContent;
  nsCOMPtr<nsIPresShell> targetPresShell;
  GetTargetIfTypeAheadOkay(aTextEvent, getter_AddRefs(targetContent), 
    getter_AddRefs(targetPresShell));
  if (!targetContent || !targetPresShell) {
    mIsIMETypeAheadActive = PR_FALSE;
    return NS_OK;
  }

  nsCOMPtr<nsIPrivateTextEvent> textEvent(do_QueryInterface(aTextEvent));
  if (!textEvent)
    return NS_OK;

  textEvent->GetText(mIMEString);

  // show the candidate char/word in the status bar
  DisplayStatus(PR_FALSE, nsnull, PR_FALSE, mIMEString.get());

  // --------- Position the IME window --------------
  // XXX - what do we do with this, is it even necessary?
  //       should we position it in a consistent place?
  nsTextEventReply *textEventReply;
  textEvent->GetEventReply(&textEventReply);

  nsCOMPtr<nsICaret> caret;
  targetPresShell->GetCaret(getter_AddRefs(caret));
  NS_ENSURE_TRUE(caret, NS_ERROR_FAILURE);

  // Reset caret coordinates, so that IM window can move with us
  caret->GetCaretCoordinates(nsICaret::eIMECoordinates, mFocusedDocSelection,
    &(textEventReply->mCursorPosition), &(textEventReply->mCursorIsCollapsed), nsnull);

  return NS_OK;
}

Here is the call graph for this function:

void nsITypeAheadFind::init ( in nsIDocShell  aDocShell) [inherited]
nsresult nsTypeAheadFind::Init ( void  ) [protected]

Definition at line 182 of file nsTypeAheadFind.cpp.

{
  nsresult rv = NS_NewISupportsArray(getter_AddRefs(mManualFindWindows));
  NS_ENSURE_SUCCESS(rv, rv);


  nsCOMPtr<nsIPrefBranch2> prefInternal(do_GetService(NS_PREFSERVICE_CONTRACTID));
  mSearchRange = do_CreateInstance(kRangeCID);
  mStartPointRange = do_CreateInstance(kRangeCID);
  mEndPointRange = do_CreateInstance(kRangeCID);
  mFind = do_CreateInstance(NS_FIND_CONTRACTID);
  if (!prefInternal || !mSearchRange || !mStartPointRange ||
      !mEndPointRange || !mFind) {
    return NS_ERROR_FAILURE;
  }

  // ----------- Listen to prefs ------------------
  rv = prefInternal->AddObserver("accessibility.typeaheadfind", this, PR_FALSE);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = prefInternal->AddObserver("accessibility.browsewithcaret", this, PR_FALSE);
  NS_ENSURE_SUCCESS(rv, rv);


  // ----------- Get accel key --------------------
  rv = prefInternal->GetIntPref("ui.key.accelKey", &sAccelKey);
  NS_ENSURE_SUCCESS(rv, rv);

  // ----------- Get initial preferences ----------
  PrefsReset();

  // ----------- Set search options ---------------
  mFind->SetCaseSensitive(PR_FALSE);
  mFind->SetWordBreaker(nsnull);

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsTypeAheadFind::IsRangeVisible ( nsIPresShell aPresShell,
nsPresContext aPresContext,
nsIDOMRange aRange,
PRBool  aMustBeVisible,
PRBool  aGetTopVisibleLeaf,
nsIDOMRange **  aNewRange,
PRBool aUsesIndependentSelection 
) [protected]

Definition at line 1194 of file nsTypeAheadFind.cpp.

{
  NS_ENSURE_ARG_POINTER(aPresShell);
  NS_ENSURE_ARG_POINTER(aPresContext);
  NS_ENSURE_ARG_POINTER(aRange);
  NS_ENSURE_ARG_POINTER(aFirstVisibleRange);

  // We need to know if the range start is visible.
  // Otherwise, return a the first visible range start 
  // in aFirstVisibleRange

  aRange->CloneRange(aFirstVisibleRange);
  nsCOMPtr<nsIDOMNode> node;
  aRange->GetStartContainer(getter_AddRefs(node));

  nsCOMPtr<nsIContent> content(do_QueryInterface(node));
  if (!content)
    return PR_FALSE;

  nsIFrame *frame = nsnull;
  aPresShell->GetPrimaryFrameFor(content, &frame);
  if (!frame)    
    return PR_FALSE;  // No frame! Not visible then.

  if (!frame->GetStyleVisibility()->IsVisible())
    return PR_FALSE;

  // Detect if we are _inside_ a text control, or something else with its own
  // selection controller.
  if (aUsesIndependentSelection) {
    *aUsesIndependentSelection = 
      (frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION);
  }

  // ---- We have a frame ----
  if (!aMustBeInViewPort)   
    return PR_TRUE; //  Don't need it to be on screen, just in rendering tree

  // Get the next in flow frame that contains the range start
  PRInt32 startRangeOffset, startFrameOffset, endFrameOffset;
  aRange->GetStartOffset(&startRangeOffset);
  while (PR_TRUE) {
    frame->GetOffsets(startFrameOffset, endFrameOffset);
    if (startRangeOffset < endFrameOffset)
      break;

    nsIFrame *nextInFlowFrame = frame->GetNextInFlow();
    if (nextInFlowFrame)
      frame = nextInFlowFrame;
    else
      break;
  }

  // Set up the variables we need, return true if we can't get at them all
  const PRUint16 kMinPixels  = 12;

  nsIViewManager* viewManager = aPresShell->GetViewManager();
  if (!viewManager)
    return PR_TRUE;

  // Get the bounds of the current frame, relative to the current view.
  // We don't use the more accurate AccGetBounds, because that is
  // more expensive and the STATE_OFFSCREEN flag that this is used
  // for only needs to be a rough indicator
  nsIView *containingView = nsnull;
  nsPoint frameOffset;
  float p2t;
  p2t = aPresContext->PixelsToTwips();
  nsRectVisibility rectVisibility = nsRectVisibility_kAboveViewport;

  if (!aGetTopVisibleLeaf) {
    nsRect relFrameRect = frame->GetRect();
    frame->GetOffsetFromView(frameOffset, &containingView);
    if (!containingView)      
      return PR_FALSE;  // no view -- not visible    

    relFrameRect.x = frameOffset.x;
    relFrameRect.y = frameOffset.y;

    viewManager->GetRectVisibility(containingView, relFrameRect,
                                   NS_STATIC_CAST(PRUint16, (kMinPixels * p2t)),
                                   &rectVisibility);

    if (rectVisibility != nsRectVisibility_kAboveViewport &&
        rectVisibility != nsRectVisibility_kZeroAreaRect) {
      return PR_TRUE;
    }
  }

  // We know that the target range isn't usable because it's not in the
  // view port. Move range forward to first visible point,
  // this speeds us up a lot in long documents
  nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
  nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID));
  if (trav)
    trav->NewFrameTraversal(getter_AddRefs(frameTraversal), LEAF, aPresContext, frame);

  if (!frameTraversal)
    return PR_FALSE;

  while (rectVisibility == nsRectVisibility_kAboveViewport || rectVisibility == nsRectVisibility_kZeroAreaRect) {
    frameTraversal->Next();
    nsISupports* currentItem;
    frameTraversal->CurrentItem(&currentItem);
    frame = NS_STATIC_CAST(nsIFrame*, currentItem);
    if (!frame)
      return PR_FALSE;

    nsRect relFrameRect = frame->GetRect();
    frame->GetOffsetFromView(frameOffset, &containingView);
    if (containingView) {
      relFrameRect.x = frameOffset.x;
      relFrameRect.y = frameOffset.y;
      viewManager->GetRectVisibility(containingView, relFrameRect,
                                     NS_STATIC_CAST(PRUint16, (kMinPixels * p2t)),
                                     &rectVisibility);
    }
  }

  if (frame) {
    nsCOMPtr<nsIDOMNode> firstVisibleNode = do_QueryInterface(frame->GetContent());

    if (firstVisibleNode) {
      (*aFirstVisibleRange)->SelectNode(firstVisibleNode);
      frame->GetOffsets(startFrameOffset, endFrameOffset);
      (*aFirstVisibleRange)->SetStart(firstVisibleNode, startFrameOffset);
      (*aFirstVisibleRange)->Collapse(PR_TRUE);  // Collapse to start
    }
  }

  return PR_FALSE;
}

Here is the call graph for this function:

PRBool nsTypeAheadFind::IsRangeVisible ( nsIPresShell aPresShell,
nsPresContext aPresContext,
nsIDOMRange aRange,
PRBool  aMustBeVisible,
PRBool  aGetTopVisibleLeaf,
nsIDOMRange **  aNewRange 
) [protected]

Definition at line 2547 of file nsTypeAheadFind.cpp.

{
  NS_ENSURE_ARG_POINTER(aPresShell);
  NS_ENSURE_ARG_POINTER(aPresContext);
  NS_ENSURE_ARG_POINTER(aRange);
  NS_ENSURE_ARG_POINTER(aFirstVisibleRange);

  // We need to know if the range start is visible.
  // Otherwise, return a the first visible range start 
  // in aFirstVisibleRange

  aRange->CloneRange(aFirstVisibleRange);
  nsCOMPtr<nsIDOMNode> node;
  aRange->GetStartContainer(getter_AddRefs(node));

  nsCOMPtr<nsIContent> content(do_QueryInterface(node));
  if (!content) {
    return PR_FALSE;
  }

  nsIFrame *frame = nsnull;
  aPresShell->GetPrimaryFrameFor(content, &frame);
  if (!frame) {
    // No frame! Not visible then.

    return PR_FALSE;
  }

  if (!frame->GetStyleVisibility()->IsVisible()) {
    return PR_FALSE;
  }


  // ---- We have a frame ----
  if (!aMustBeInViewPort) {
    //  Don't need it to be on screen, just in rendering tree

    return PR_TRUE;
  }

  // Get the next in flow frame that contains the range start
  PRInt32 startRangeOffset, startFrameOffset, endFrameOffset;
  aRange->GetStartOffset(&startRangeOffset);
  while (PR_TRUE) {
    frame->GetOffsets(startFrameOffset, endFrameOffset);
    if (startRangeOffset < endFrameOffset) {
      break;
    }
    nsIFrame *nextInFlowFrame = frame->GetNextInFlow();
    if (nextInFlowFrame) {
      frame = nextInFlowFrame;
    }
    else {
      break;
    }
  }

  // Set up the variables we need, return true if we can't get at them all
  const PRUint16 kMinPixels  = 12;

  nsIViewManager* viewManager = aPresShell->GetViewManager();
  if (!viewManager) {
    return PR_TRUE;
  }

  // Get the bounds of the current frame, relative to the current view.
  // We don't use the more accurate AccGetBounds, because that is
  // more expensive and the STATE_OFFSCREEN flag that this is used
  // for only needs to be a rough indicator
  nsIView *containingView = nsnull;
  nsPoint frameOffset;
  float p2t;
  p2t = aPresContext->PixelsToTwips();
  nsRectVisibility rectVisibility = nsRectVisibility_kAboveViewport;

  if (!aGetTopVisibleLeaf) {
    nsRect relFrameRect = frame->GetRect();
    frame->GetOffsetFromView(frameOffset, &containingView);
    if (!containingView) {
      // no view -- not visible

      return PR_FALSE;
    }

    relFrameRect.x = frameOffset.x;
    relFrameRect.y = frameOffset.y;

    viewManager->GetRectVisibility(containingView, relFrameRect,
                                   NS_STATIC_CAST(PRUint16, (kMinPixels * p2t)),
                                   &rectVisibility);

    if (rectVisibility != nsRectVisibility_kAboveViewport &&
        rectVisibility != nsRectVisibility_kZeroAreaRect) {
      return PR_TRUE;
    }
  }

  // We know that the target range isn't usable because it's not in the
  // view port. Move range forward to first visible point,
  // this speeds us up a lot in long documents
  nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
  nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID));
  if (trav) {
    trav->NewFrameTraversal(getter_AddRefs(frameTraversal), LEAF,
                            aPresContext, frame);
  }

  if (!frameTraversal) {
    return PR_FALSE;
  }

  while (rectVisibility == nsRectVisibility_kAboveViewport ||
         rectVisibility == nsRectVisibility_kZeroAreaRect) {
    frameTraversal->Next();
    nsISupports* currentItem;
    frameTraversal->CurrentItem(&currentItem);
    frame = NS_STATIC_CAST(nsIFrame*, currentItem);
    if (!frame) {
      return PR_FALSE;
    }

    nsRect relFrameRect = frame->GetRect();
    frame->GetOffsetFromView(frameOffset, &containingView);
    if (containingView) {
      relFrameRect.x = frameOffset.x;
      relFrameRect.y = frameOffset.y;
      viewManager->GetRectVisibility(containingView, relFrameRect,
                                     NS_STATIC_CAST(PRUint16,
                                                    (kMinPixels * p2t)),
                                     &rectVisibility);
    }
  }

  if (frame) {
    nsCOMPtr<nsIDOMNode> firstVisibleNode =
      do_QueryInterface(frame->GetContent());

    if (firstVisibleNode) {
      (*aFirstVisibleRange)->SelectNode(firstVisibleNode);
      frame->GetOffsets(startFrameOffset, endFrameOffset);
      (*aFirstVisibleRange)->SetStart(firstVisibleNode, startFrameOffset);
      (*aFirstVisibleRange)->Collapse(PR_TRUE);  // Collapse to start
    }
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2404 of file nsTypeAheadFind.cpp.

{
  if (!aContent) {
    return PR_FALSE;
  }

  if (aContent->IsContentOfType(nsIContent::eHTML_FORM_CONTROL)) {
    nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(aContent));
    PRInt32 controlType = formControl->GetType();
    if (controlType == NS_FORM_SELECT || 
        controlType == NS_FORM_TEXTAREA ||
        controlType == NS_FORM_INPUT_TEXT ||
        controlType == NS_FORM_INPUT_PASSWORD ||
        controlType == NS_FORM_INPUT_FILE) {
      // Don't steal keys from these form controls 
      // - selects have their own incremental find for options
      // - text fields need to allow typing
      return PR_FALSE;
    }
  }
  else if (aContent->IsContentOfType(nsIContent::eHTML)) {
    // Test for isindex, a deprecated kind of text field. We're using a string 
    // compare because <isindex> is not considered a form control, so it does 
    // not support nsIFormControl or eHTML_FORM_CONTROL, and it's not worth 
    // having a table of atoms just for it. Instead, we're paying for 1 extra 
    // string compare per keystroke, which isn't too bad.
    const char *tagStr;
    aContent->Tag()->GetUTF8String(&tagStr);
    if (strcmp(tagStr, "isindex") == 0) {
      return PR_FALSE;
    }
  }

  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Processes a key pressed event.

Parameters:
aKeyEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMKeyListener.

Definition at line 592 of file nsTypeAheadFind.cpp.

{
  return NS_OK;
}

Processes a key typed event.

Parameters:
aKeyEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMKeyListener.

Definition at line 606 of file nsTypeAheadFind.cpp.

{
  if (!mIsTypeAheadOn || mIsMenuBarActive || mIsMenuPopupActive) {
    return NS_OK;
  }

  if (!mIsSoundInitialized && !mNotFoundSoundURL.IsEmpty()) {
    // This makes sure system sound library is loaded so that
    // there's no lag before the first sound is played
    // by waiting for the first keystroke, we still get the startup time benefits.
    mIsSoundInitialized = PR_TRUE;
    mSoundInterface = do_CreateInstance("@mozilla.org/sound;1");
    if (mSoundInterface && !mNotFoundSoundURL.EqualsLiteral("beep")) {
      mSoundInterface->Init();
    }
  }

#ifdef XP_WIN
  // After each keystroke, ensure sound object is destroyed, to free up memory 
  // allocated for error sound, otherwise Windows' nsISound impl 
  // holds onto the last played sound, using up memory.
  mSoundInterface = nsnull;
#endif
  nsCOMPtr<nsIContent> targetContent;
  nsCOMPtr<nsIPresShell> targetPresShell;
  GetTargetIfTypeAheadOkay(aEvent, getter_AddRefs(targetContent), 
    getter_AddRefs(targetPresShell));
  if (!targetContent || !targetPresShell)
    return NS_OK;

  PRUint32 keyCode(0), charCode;
  PRBool isShift(PR_FALSE), isCtrl(PR_FALSE), isAlt(PR_FALSE), isMeta(PR_FALSE);
  nsCOMPtr<nsIDOMKeyEvent> keyEvent(do_QueryInterface(aEvent));

  // ---------- Analyze keystroke, exit early if possible --------------

  if (!keyEvent ||
      NS_FAILED(keyEvent->GetKeyCode(&keyCode)) ||
      NS_FAILED(keyEvent->GetCharCode(&charCode)) ||
      NS_FAILED(keyEvent->GetShiftKey(&isShift)) ||
      NS_FAILED(keyEvent->GetCtrlKey(&isCtrl)) ||
      NS_FAILED(keyEvent->GetAltKey(&isAlt)) ||
      NS_FAILED(keyEvent->GetMetaKey(&isMeta))) {
    return NS_ERROR_FAILURE;
  }

  // ---------- Set Backspace Protection --------------------------
  // mIsBackspaceProtectOn should be PR_TRUE only if the last key 
  // was a backspace and this key is also a backspace. It keeps us 
  // from accidentally hitting backspace too many times in a row, going 
  // back in history when we really just wanted to clear the find string.
  if (keyCode != nsIDOMKeyEvent::DOM_VK_BACK_SPACE) {
    mIsBackspaceProtectOn = PR_FALSE;
  }

  // ---------- Check the keystroke --------------------------------
  if ((isAlt && !isShift) || isCtrl || isMeta) {
    // Ignore most modified keys, but alt+shift may be used for
    // entering foreign chars.

    return NS_OK;
  }

  // ------------- Escape pressed ---------------------
  if (keyCode == nsIDOMKeyEvent::DOM_VK_ESCAPE) {
    // Escape accomplishes 2 things:
    // 1. it is a way for the user to deselect with the keyboard
    // 2. it is a way for the user to cancel incremental find with
    //    visual feedback
    if (mLinksOnlyManuallySet || !mTypeAheadBuffer.IsEmpty()) {
      // If Escape is normally used for a command, don't do it
      aEvent->PreventDefault();
      CancelFind();
    }
    if (mFocusedDocSelection) {
      SetSelectionLook(targetPresShell, PR_FALSE, PR_FALSE);
      mFocusedDocSelection->CollapseToStart();
    }

    return NS_OK;
  }

  // ---------- PreventDefault check ---------------
  // If a web page wants to use printable character keys,
  // they have to use evt.preventDefault() after they get the key
  nsCOMPtr<nsIDOMNSUIEvent> uiEvent(do_QueryInterface(aEvent));
  PRBool preventDefault;
  uiEvent->GetPreventDefault(&preventDefault);
  if (preventDefault) {
    return NS_OK;
  }

  // ----------- Back space -------------------------
  if (keyCode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE) {
    // The order of seeing keystrokes is:
    // 1) Chrome, 2) Typeahead, 3) [platform]HTMLBindings.xml
    // If chrome handles backspace, it needs to do this work
    // Otherwise, we handle backspace here.
    PRBool backspaceUsed;
    BackOneChar(&backspaceUsed);
    if (backspaceUsed) {
      aEvent->PreventDefault(); // Prevent normal processing of this keystroke
    }

    return NS_OK;
  }
  
  // ----------- Other non-printable keys -----------
  // We ignore space only if it's the first character
  // Function keys, etc. exit here
  if (keyCode || charCode < ' ' || 
      (charCode == ' ' && mTypeAheadBuffer.IsEmpty())) {
    return NS_OK;
  }

  // Ignore first / or ' -- they are used to set links/text only
  // Needs to come to us through htmlBindings.xml's keybinding
  // then via nsTypeAheadController::DoCommand()
  if (!mLinksOnlyManuallySet && (charCode == '\'' || charCode == '/') && 
      mTypeAheadBuffer.IsEmpty()) {
    return NS_OK;
  }

  aEvent->StopPropagation();  // We're using this key, no one else should

  return HandleChar(charCode);
}

Here is the call graph for this function:

NS_IMETHODIMP nsTypeAheadFind::KeyUp ( nsIDOMEvent aKeyEvent) [virtual]

Processes a key release event.

Parameters:
aKeyEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMKeyListener.

Definition at line 599 of file nsTypeAheadFind.cpp.

{
  return NS_OK;
}
void nsITimerCallback::notify ( in nsITimer  timer) [inherited]
Parameters:
aTimerthe timer which has expired
void nsISelectionListener::notifySelectionChanged ( in nsIDOMDocument  doc,
in nsISelection  sel,
in short  reason 
) [inherited]
void nsIObserver::observe ( in nsISupports  aSubject,
in string  aTopic,
in wstring  aData 
) [inherited]

Observe will be called when there is a notification for the topic |aTopic|.

This assumes that the object implementing this interface has been registered with an observer service such as the nsIObserverService.

If you expect multiple topics/subjects, the impl is responsible for filtering.

You should not modify, add, remove, or enumerate notifications in the implemention of observe.

Parameters:
aSubject: Notification specific interface pointer.
aTopic: The notification topic or subject.
aData: Notification specific wide string. subject event.

Definition at line 1070 of file nsTypeAheadFind.cpp.

{
  if (mNotFoundSoundURL.IsEmpty())    // no sound
    return;
  if (!mSoundInterface) {
    mSoundInterface = do_CreateInstance("@mozilla.org/sound;1");
  }
  if (mSoundInterface) {
    mIsSoundInitialized = PR_TRUE;

    if (mNotFoundSoundURL.Equals("beep")) {
      mSoundInterface->Beep();
      return;
    }

    nsCOMPtr<nsIURI> soundURI;
    if (mNotFoundSoundURL.Equals("default"))
      NS_NewURI(getter_AddRefs(soundURI),
                NS_LITERAL_CSTRING(TYPEAHEADFIND_NOTFOUND_WAV_URL));
    else
      NS_NewURI(getter_AddRefs(soundURI), mNotFoundSoundURL);
    nsCOMPtr<nsIURL> soundURL(do_QueryInterface(soundURI));
    if (soundURL) {
      mSoundInterface->Play(soundURL);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 267 of file nsTypeAheadFind.cpp.

{
  nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
  NS_ENSURE_TRUE(prefBranch, NS_ERROR_FAILURE);

  PRBool wasTypeAheadOn = mIsTypeAheadOn;

  prefBranch->GetBoolPref("accessibility.typeaheadfind", &mIsTypeAheadOn);

  if (mIsTypeAheadOn != wasTypeAheadOn) {
    if (!mIsTypeAheadOn) {
      CancelFind();
    }
    else if (!mStringBundle) {
      // Get ready to watch windows
      nsresult rv;
      nsCOMPtr<nsIWindowWatcher> windowWatcher =
        do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
      NS_ENSURE_SUCCESS(rv, rv);

      windowWatcher->RegisterNotification(this);

      // Initialize string bundle
      nsCOMPtr<nsIStringBundleService> stringBundleService =
        do_GetService(kStringBundleServiceCID);

      if (stringBundleService)
        stringBundleService->CreateBundle(TYPEAHEADFIND_BUNDLE_URL,
                                          getter_AddRefs(mStringBundle));

      // Observe find again commands. We'll handle them if we were the last find
      nsCOMPtr<nsIObserverService> observerService = 
        do_GetService("@mozilla.org/observer-service;1", &rv);
      NS_ENSURE_SUCCESS(rv, rv);
      observerService->AddObserver(this, "nsWebBrowserFind_FindAgain", 
                                   PR_TRUE);
      observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, 
                                   PR_TRUE);
    }
  }

  PRBool oldAutoStartPref = mAutoStartPref;
  prefBranch->GetBoolPref("accessibility.typeaheadfind.autostart",
                           &mAutoStartPref);
  if (mAutoStartPref != oldAutoStartPref) {
    ResetGlobalAutoStart(mAutoStartPref);
  }
 
  prefBranch->GetBoolPref("accessibility.typeaheadfind.linksonly",
                          &mLinksOnlyPref);

  prefBranch->GetBoolPref("accessibility.typeaheadfind.startlinksonly",
                          &mStartLinksOnlyPref);

  PRBool isSoundEnabled = PR_TRUE;
  prefBranch->GetBoolPref("accessibility.typeaheadfind.enablesound",
                           &isSoundEnabled);
  nsXPIDLCString soundStr;
  if (isSoundEnabled) {
    prefBranch->GetCharPref("accessibility.typeaheadfind.soundURL",
                             getter_Copies(soundStr));
  }
  mNotFoundSoundURL = soundStr;

  PRBool isTimeoutEnabled = PR_FALSE;
  prefBranch->GetBoolPref("accessibility.typeaheadfind.enabletimeout",
                          &isTimeoutEnabled);
  PRInt32 timeoutLength = 0;
  if (isTimeoutEnabled) {
    prefBranch->GetIntPref("accessibility.typeaheadfind.timeout",
                           &timeoutLength);
  }
  mTimeoutLength = timeoutLength;


  prefBranch->GetBoolPref("accessibility.browsewithcaret",
                          &mCaretBrowsingOn);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTypeAheadFind::RangeStartsInsideLink ( nsIDOMRange aRange,
nsIPresShell aPresShell,
PRBool aIsInsideLink,
PRBool aIsStartingLink 
) [protected]
void nsTypeAheadFind::RangeStartsInsideLink ( nsIDOMRange aRange,
nsIPresShell aPresShell,
PRBool aIsInsideLink,
PRBool aIsStartingLink 
) [protected]

Definition at line 1576 of file nsTypeAheadFind.cpp.

{
  *aIsInsideLink = PR_FALSE;
  *aIsStartingLink = PR_TRUE;

  // ------- Get nsIContent to test -------
  nsCOMPtr<nsIDOMNode> startNode;
  nsCOMPtr<nsIContent> startContent, origContent;
  aRange->GetStartContainer(getter_AddRefs(startNode));
  PRInt32 startOffset;
  aRange->GetStartOffset(&startOffset);

  startContent = do_QueryInterface(startNode);
  if (!startContent) {
    NS_NOTREACHED("startContent should never be null");
    return;
  }
  origContent = startContent;

  if (startContent->IsContentOfType(nsIContent::eELEMENT)) {
    nsIContent *childContent = startContent->GetChildAt(startOffset);
    if (childContent) {
      startContent = childContent;
    }
  }
  else if (startOffset > 0) {
    nsCOMPtr<nsITextContent> textContent(do_QueryInterface(startContent));

    if (textContent) {
      // look for non whitespace character before start offset
      const nsTextFragment *textFrag = textContent->Text();

      for (PRInt32 index = 0; index < startOffset; index++) {
        if (!XP_IS_SPACE(textFrag->CharAt(index))) {
          *aIsStartingLink = PR_FALSE;  // not at start of a node

          break;
        }
      }
    }
  }

  // ------- Check to see if inside link ---------

  // We now have the correct start node for the range
  // Search for links, starting with startNode, and going up parent chain

  nsCOMPtr<nsIAtom> tag, hrefAtom(do_GetAtom("href"));
  nsCOMPtr<nsIAtom> typeAtom(do_GetAtom("type"));

  while (PR_TRUE) {
    // Keep testing while textContent is equal to something,
    // eventually we'll run out of ancestors

    if (startContent->IsContentOfType(nsIContent::eHTML)) {
      nsCOMPtr<nsILink> link(do_QueryInterface(startContent));
      if (link) {
        // Check to see if inside HTML link
        *aIsInsideLink = startContent->HasAttr(kNameSpaceID_None, hrefAtom);
        return;
      }
    }
    else {
      // Any xml element can be an xlink
      *aIsInsideLink = startContent->HasAttr(kNameSpaceID_XLink, hrefAtom);
      if (*aIsInsideLink) {
        nsAutoString xlinkType;
        startContent->GetAttr(kNameSpaceID_XLink, typeAtom, xlinkType);
        if (!xlinkType.EqualsLiteral("simple")) {
          *aIsInsideLink = PR_FALSE;  // Xlink must be type="simple"
        }

        return;
      }
    }

    // Get the parent
    nsCOMPtr<nsIContent> parent = startContent->GetParent();
    if (parent) {
      nsIContent *parentsFirstChild = parent->GetChildAt(0);
      nsCOMPtr<nsITextContent> textContent =
        do_QueryInterface(parentsFirstChild);

      // We don't want to look at a whitespace-only first child
      if (textContent && textContent->IsOnlyWhitespace())
        parentsFirstChild = parent->GetChildAt(1);

      if (parentsFirstChild != startContent) {
        // startContent wasn't a first child, so we conclude that
        // if this is inside a link, it's not at the beginning of it
        *aIsStartingLink = PR_FALSE;
      }

      startContent = parent;
    }
    else
      break;
  }

  *aIsStartingLink = PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 244 of file nsTypeAheadFind.cpp.

Here is the caller graph for this function:

Definition at line 2214 of file nsTypeAheadFind.cpp.

{
  nsCOMPtr<nsIPresShell> presShell(GetPresShell());
  nsIViewManager* vm = nsnull;

  if (presShell) {
    vm = presShell->GetViewManager();
  }

  nsIScrollableView* scrollableView = nsnull;
  if (vm) {
    vm->GetRootScrollableView(&scrollableView);
  }

  if (scrollableView) {
    scrollableView->RemoveScrollPositionListener(this);
  }

  mFocusedWeakShell = nsnull;

  // Remove selection listener
  nsCOMPtr<nsISelectionPrivate> selPrivate =
    do_QueryInterface(mFocusedDocSelection);

  if (selPrivate) {
    selPrivate->RemoveSelectionListener(this); // remove us if we're a listener
  }

  mFocusedDocSelection = nsnull;
  mFocusedDocSelCon = nsnull; // Selection controller owns pres shell!
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2278 of file nsTypeAheadFind.cpp.

{
  nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
  GetChromeEventHandler(aDOMWin, getter_AddRefs(chromeEventHandler));
  if (!chromeEventHandler) {
    return;
  }

  // Use capturing, otherwise the normal find next will get activated when ours should
  nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(chromeEventHandler));
  nsCOMPtr<nsIDOMEventGroup> systemGroup;
  receiver->GetSystemEventGroup(getter_AddRefs(systemGroup));
  nsCOMPtr<nsIDOM3EventTarget> target(do_QueryInterface(receiver));

  target->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"),
                                     NS_STATIC_CAST(nsIDOMKeyListener*, this),
                                     PR_FALSE, systemGroup);

  if (aDOMWin == mFocusedWindow) {
    mFocusedWindow = nsnull;
  }

  // Remove menu listeners
  nsIDOMEventListener *genericEventListener = 
    NS_STATIC_CAST(nsIDOMEventListener*, NS_STATIC_CAST(nsIDOMKeyListener*, this));

  chromeEventHandler->RemoveEventListener(NS_LITERAL_STRING("popupshown"), 
                                          genericEventListener, 
                                          PR_TRUE);

  chromeEventHandler->RemoveEventListener(NS_LITERAL_STRING("popuphidden"), 
                                          genericEventListener, 
                                          PR_TRUE);

  chromeEventHandler->RemoveEventListener(NS_LITERAL_STRING("DOMMenuBarActive"), 
                                          genericEventListener, 
                                          PR_TRUE);

  chromeEventHandler->RemoveEventListener(NS_LITERAL_STRING("DOMMenuBarInactive"), 
                                          genericEventListener, 
                                          PR_TRUE);

  chromeEventHandler->RemoveEventListener(NS_LITERAL_STRING("unload"), 
                                          genericEventListener, 
                                          PR_TRUE);

  // Remove DOM Text listener for IME text events
  nsCOMPtr<nsIDOMEventReceiver> chromeEventReceiver = 
    do_QueryInterface(chromeEventHandler);
  chromeEventReceiver->RemoveEventListenerByIID(NS_STATIC_CAST(nsIDOMTextListener*, this), 
    NS_GET_IID(nsIDOMTextListener));
  chromeEventReceiver->RemoveEventListenerByIID(NS_STATIC_CAST(nsIDOMCompositionListener*, this), 
    NS_GET_IID(nsIDOMCompositionListener));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTypeAheadFind::ResetGlobalAutoStart ( PRBool  aAutoStart) [protected]

Definition at line 1881 of file nsTypeAheadFind.cpp.

{
  // Enumerate through the current top level windows
  // and either attach or remove window listeners

  CancelFind();

  nsCOMPtr<nsIWindowWatcher> windowWatcher =
    do_GetService(NS_WINDOWWATCHER_CONTRACTID);
  if (!windowWatcher) {
    return;
  }

  nsCOMPtr<nsISimpleEnumerator> enumerator;
  windowWatcher->GetWindowEnumerator(getter_AddRefs(enumerator));
  if (!enumerator) {
    return;
  }

  PRBool hasMoreWindows;
  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreWindows))
         && hasMoreWindows) {
    nsCOMPtr<nsISupports> supports;
    enumerator->GetNext(getter_AddRefs(supports));
    nsCOMPtr<nsIDOMWindow> domWin(do_QueryInterface(supports));
    if (domWin) {
      if (aAutoStart) {
        AttachWindowListeners(domWin);
      }
      else {
        RemoveWindowListeners(domWin);
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1042 of file nsTypeAheadFind.cpp.

{
  // Store find string for find-next
  mFindNextBuffer = mTypeAheadBuffer;
  if (mLastBadChar) {
    mFindNextBuffer.Append(mLastBadChar);
  }

  nsCOMPtr<nsIWebBrowserFind> webBrowserFind;
  GetWebBrowserFind(mFocusedWindow, getter_AddRefs(webBrowserFind));
  if (webBrowserFind) {
    webBrowserFind->SetSearchString(PromiseFlatString(mTypeAheadBuffer).get());
  }

  if (!mFindService) {
    mFindService = do_GetService("@mozilla.org/find/find_service;1");
  }
  if (mFindService) {
    mFindService->SetSearchString(mFindNextBuffer);
  }

  // --- If accessibility.typeaheadfind.timeout is set,
  //     cancel find after specified # milliseconds ---
  StartTimeout();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Implements nsIScrollPositionListener.

Definition at line 1691 of file nsTypeAheadFind.cpp.

{
  if (!mIsFindingText)
    CancelFind();

  return NS_OK;
}

Implements nsIScrollPositionListener.

Definition at line 1683 of file nsTypeAheadFind.cpp.

{
  return NS_OK;
}
void nsITypeAheadFind::setAutoStart ( in nsIDOMWindow  aWindow,
in boolean  aIsAutoStartOn 
) [inherited]

Will find as you type start automatically if the user types with the focus on page content other than a textfield or select? If autostart is off, the startNewFind() method can be used to enact type ahead find, as well as cmd_findTypeLinks or cmd_findTypeText.

void nsITypeAheadFind::setDocShell ( in nsIDocShell  aDocShell) [inherited]
void nsTypeAheadFind::SetSelectionLook ( nsIPresShell aPresShell,
PRBool  aChangeColor,
PRBool  aEnabled 
) [protected]

Definition at line 2162 of file nsTypeAheadFind.cpp.

{
  if (!aPresShell || !mFocusedDocSelCon)
    return;

  // Show caret when type ahead find is on
  // Also paint selection bright (typeaheadfind on) or normal
  // (typeaheadfind off)

  if (aChangeColor) {
    mFocusedDocSelCon->SetDisplaySelection(nsISelectionController::SELECTION_ATTENTION);
  } else {
    mFocusedDocSelCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
  }

  mFocusedDocSelCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);

  if (mCaretBrowsingOn) {
    return;  // Leave caret visibility as it is
  }

  nsCOMPtr<nsICaret> caret;
  aPresShell->GetCaret(getter_AddRefs(caret));
  nsCOMPtr<nsILookAndFeel> lookNFeel(do_GetService(kLookAndFeelCID));
  if (!caret || !lookNFeel) {
    return;
  }

  if (aEnabled) {
    // Set caret visible so that it's obvious we're in a live mode
    caret->SetCaretDOMSelection(mFocusedDocSelection);
    caret->SetVisibilityDuringSelection(PR_TRUE);
    caret->SetCaretVisible(PR_TRUE);
    mFocusedDocSelCon->SetCaretEnabled(PR_TRUE);
  }
  else {
    PRInt32 isCaretVisibleDuringSelection = 0;
    lookNFeel->GetMetric(nsILookAndFeel::eMetric_ShowCaretDuringSelection,
                         isCaretVisibleDuringSelection);
    caret->SetVisibilityDuringSelection(isCaretVisibleDuringSelection != 0);
    nsCOMPtr<nsISelection> caretDomSelection;
    caret->GetCaretDOMSelection(getter_AddRefs(caretDomSelection));
    if (mFocusedDocSelection == caretDomSelection)  {
      mFocusedDocSelCon->SetCaretEnabled(isCaretVisibleDuringSelection != 0);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 251 of file nsTypeAheadFind.cpp.

{
  // Application shutdown 
  mTimer = nsnull;

  nsCOMPtr<nsIWindowWatcher> windowWatcher =
    do_GetService(NS_WINDOWWATCHER_CONTRACTID);
  if (windowWatcher) {
    windowWatcher->UnregisterNotification(this);
  }
}

Here is the call graph for this function:

void nsITypeAheadFind::startNewFind ( in nsIDOMWindow  aWindow,
in boolean  aLinksOnly 
) [inherited]

Manually start type ahead find mode.

Definition at line 2146 of file nsTypeAheadFind.cpp.

{
  if (mTimeoutLength) {
    if (!mTimer) {
      mTimer = do_CreateInstance("@mozilla.org/timer;1");
      if (mTimer) {
        mTimer->InitWithCallback(this, mTimeoutLength, nsITimer::TYPE_ONE_SHOT);
      }
    }
    else {
      mTimer->SetDelay(mTimeoutLength);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 479 of file nsTypeAheadFind.cpp.

{
  NS_ENSURE_ARG_POINTER(aDOMWin);

  // Set member variables and listeners up for new window and doc

  mFindNextBuffer.Truncate();
  CancelFind();

  GetStartWindow(aDOMWin, getter_AddRefs(mFocusedWindow));

  nsCOMPtr<nsIDOMDocument> domDoc;
  aDOMWin->GetDocument(getter_AddRefs(domDoc));
  nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));

  if (!doc) {
    return NS_OK;
  }

  nsIPresShell *presShell = doc->GetShellAt(0);

  if (!presShell) {
    return NS_OK;
  }

  nsCOMPtr<nsIPresShell> oldPresShell(GetPresShell());

  if (!oldPresShell || oldPresShell != presShell) {
    CancelFind();
  } else if (presShell == oldPresShell) {
    // Same window, no need to reattach listeners

    return NS_OK;
  }

  RemoveDocListeners();

  mIsFindAllowedInWindow = PR_TRUE;
  mFocusedWeakShell = do_GetWeakReference(presShell);

  // Add scroll position and selection listeners, so we can cancel
  // current find when user navigates
  GetSelection(presShell, getter_AddRefs(mFocusedDocSelCon),
               getter_AddRefs(mFocusedDocSelection)); // cache for reuse
  AttachDocListeners(presShell);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 91 of file nsITypeAheadFind.idl.

Definition at line 94 of file nsITypeAheadFind.idl.

Definition at line 47 of file nsISelectionListener.idl.

const unsigned short nsITypeAheadFind::FIND_FOUND = 0 [inherited]

Definition at line 101 of file nsITypeAheadFind.idl.

const unsigned short nsITypeAheadFind::FIND_NOTFOUND = 1 [inherited]

Definition at line 103 of file nsITypeAheadFind.idl.

const unsigned short nsITypeAheadFind::FIND_WRAPPED = 2 [inherited]

Definition at line 105 of file nsITypeAheadFind.idl.

Definition at line 90 of file nsITypeAheadFind.idl.

Definition at line 133 of file nsITypeAheadFind.idl.

Definition at line 92 of file nsITypeAheadFind.idl.

Is type ahead find mode currently on?

Definition at line 58 of file nsITypeAheadFind.idl.

Definition at line 50 of file nsISelectionListener.idl.

Definition at line 214 of file nsTypeAheadFind.h.

Definition at line 204 of file nsTypeAheadFind.h.

Definition at line 226 of file nsTypeAheadFind.h.

Definition at line 209 of file nsTypeAheadFind.h.

Definition at line 132 of file nsTypeAheadFind.h.

Definition at line 159 of file nsTypeAheadFind.h.

Definition at line 211 of file nsTypeAheadFind.h.

Definition at line 242 of file nsTypeAheadFind.h.

Definition at line 245 of file nsTypeAheadFind.h.

Definition at line 195 of file nsTypeAheadFind.h.

Definition at line 246 of file nsTypeAheadFind.h.

Definition at line 249 of file nsTypeAheadFind.h.

Definition at line 253 of file nsTypeAheadFind.h.

Definition at line 252 of file nsTypeAheadFind.h.

Definition at line 255 of file nsTypeAheadFind.h.

Definition at line 254 of file nsTypeAheadFind.h.

Definition at line 131 of file nsTypeAheadFind.h.

Definition at line 130 of file nsTypeAheadFind.h.

Definition at line 196 of file nsTypeAheadFind.h.

Definition at line 225 of file nsTypeAheadFind.h.

Definition at line 203 of file nsTypeAheadFind.h.

Definition at line 220 of file nsTypeAheadFind.h.

Definition at line 223 of file nsTypeAheadFind.h.

Definition at line 224 of file nsTypeAheadFind.h.

Definition at line 221 of file nsTypeAheadFind.h.

Definition at line 222 of file nsTypeAheadFind.h.

Definition at line 234 of file nsTypeAheadFind.h.

Definition at line 208 of file nsTypeAheadFind.h.

Definition at line 227 of file nsTypeAheadFind.h.

Definition at line 141 of file nsTypeAheadFind.h.

Definition at line 207 of file nsTypeAheadFind.h.

Definition at line 217 of file nsTypeAheadFind.h.

Definition at line 205 of file nsTypeAheadFind.h.

Definition at line 210 of file nsTypeAheadFind.h.

Definition at line 258 of file nsTypeAheadFind.h.

Definition at line 198 of file nsTypeAheadFind.h.

Definition at line 48 of file nsISelectionListener.idl.

Definition at line 49 of file nsISelectionListener.idl.

Definition at line 160 of file nsTypeAheadFind.h.

Definition at line 228 of file nsTypeAheadFind.h.

Definition at line 240 of file nsTypeAheadFind.h.

Definition at line 161 of file nsTypeAheadFind.h.

Definition at line 233 of file nsTypeAheadFind.h.

Definition at line 239 of file nsTypeAheadFind.h.

Definition at line 206 of file nsTypeAheadFind.h.

Definition at line 241 of file nsTypeAheadFind.h.

Definition at line 247 of file nsTypeAheadFind.h.

Definition at line 229 of file nsTypeAheadFind.h.

Definition at line 248 of file nsTypeAheadFind.h.

Definition at line 194 of file nsTypeAheadFind.h.

Definition at line 156 of file nsTypeAheadFind.h.

const short nsISelectionListener::NO_REASON = 0 [inherited]

Definition at line 46 of file nsISelectionListener.idl.

PRInt32 nsTypeAheadFind::sAccelKey = -1 [static, protected]

Definition at line 236 of file nsTypeAheadFind.h.

readonly attribute AString nsITypeAheadFind::searchString [inherited]

Definition at line 88 of file nsITypeAheadFind.idl.

Definition at line 51 of file nsISelectionListener.idl.

Definition at line 191 of file nsTypeAheadFind.h.


The documentation for this class was generated from the following files: