2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
*
|
2012-05-21 04:12:37 -07:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsWebBrowserFind.h"
|
|
|
|
|
|
|
|
// Only need this for NS_FIND_CONTRACTID,
|
|
|
|
// else we could use nsIDOMRange.h and nsIFind.h.
|
|
|
|
#include "nsFind.h"
|
|
|
|
|
|
|
|
#include "nsIComponentManager.h"
|
|
|
|
#include "nsIScriptSecurityManager.h"
|
|
|
|
#include "nsIInterfaceRequestor.h"
|
|
|
|
#include "nsIInterfaceRequestorUtils.h"
|
|
|
|
#include "nsPIDOMWindow.h"
|
|
|
|
#include "nsIURI.h"
|
|
|
|
#include "nsIDocShell.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsPresContext.h"
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIDOMDocument.h"
|
|
|
|
#include "nsISelectionController.h"
|
|
|
|
#include "nsISelection.h"
|
|
|
|
#include "nsIFrame.h"
|
|
|
|
#include "nsITextControlFrame.h"
|
|
|
|
#include "nsReadableUtils.h"
|
|
|
|
#include "nsIDOMHTMLElement.h"
|
|
|
|
#include "nsIDOMHTMLDocument.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsContentCID.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsIObserverService.h"
|
|
|
|
#include "nsISupportsPrimitives.h"
|
2007-06-18 20:01:03 -07:00
|
|
|
#include "nsFind.h"
|
2012-07-27 07:03:27 -07:00
|
|
|
#include "nsError.h"
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
#include "nsFocusManager.h"
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 09:59:13 -07:00
|
|
|
#include "mozilla/Services.h"
|
2013-07-23 16:39:17 -07:00
|
|
|
#include "mozilla/dom/Element.h"
|
2013-09-06 10:50:24 -07:00
|
|
|
#include "nsISimpleEnumerator.h"
|
2014-05-06 15:43:03 -07:00
|
|
|
#include "nsContentUtils.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
#include "nsIWebNavigation.h"
|
|
|
|
#include "nsXPIDLString.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//*****************************************************************************
|
|
|
|
// nsWebBrowserFind
|
|
|
|
//*****************************************************************************
|
|
|
|
|
|
|
|
nsWebBrowserFind::nsWebBrowserFind() :
|
2011-10-17 07:59:28 -07:00
|
|
|
mFindBackwards(false),
|
|
|
|
mWrapFind(false),
|
|
|
|
mEntireWord(false),
|
|
|
|
mMatchCase(false),
|
|
|
|
mSearchSubFrames(true),
|
|
|
|
mSearchParentFrames(true)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsWebBrowserFind::~nsWebBrowserFind()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-04-27 00:06:00 -07:00
|
|
|
NS_IMPL_ISUPPORTS(nsWebBrowserFind, nsIWebBrowserFind, nsIWebBrowserFindInFrames)
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
|
|
|
|
/* boolean findNext (); */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::FindNext(bool *outDidFind)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(outDidFind);
|
2011-10-17 07:59:28 -07:00
|
|
|
*outDidFind = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
NS_ENSURE_TRUE(CanFindNext(), NS_ERROR_NOT_INITIALIZED);
|
|
|
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIDOMWindow> searchFrame = do_QueryReferent(mCurrentSearchFrame);
|
|
|
|
NS_ENSURE_TRUE(searchFrame, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMWindow> rootFrame = do_QueryReferent(mRootSearchFrame);
|
|
|
|
NS_ENSURE_TRUE(rootFrame, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
|
|
|
|
// first, if there's a "cmd_findagain" observer around, check to see if it
|
|
|
|
// wants to perform the find again command . If it performs the find again
|
|
|
|
// it will return true, in which case we exit ::FindNext() early.
|
|
|
|
// Otherwise, nsWebBrowserFind needs to perform the find again command itself
|
|
|
|
// this is used by nsTypeAheadFind, which controls find again when it was
|
|
|
|
// the last executed find in the current window.
|
|
|
|
nsCOMPtr<nsIObserverService> observerSvc =
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 09:59:13 -07:00
|
|
|
mozilla::services::GetObserverService();
|
2007-03-22 10:30:00 -07:00
|
|
|
if (observerSvc) {
|
|
|
|
nsCOMPtr<nsISupportsInterfacePointer> windowSupportsData =
|
|
|
|
do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsCOMPtr<nsISupports> searchWindowSupports =
|
|
|
|
do_QueryInterface(rootFrame);
|
|
|
|
windowSupportsData->SetData(searchWindowSupports);
|
|
|
|
NS_NAMED_LITERAL_STRING(dnStr, "down");
|
|
|
|
NS_NAMED_LITERAL_STRING(upStr, "up");
|
|
|
|
observerSvc->NotifyObservers(windowSupportsData,
|
|
|
|
"nsWebBrowserFind_FindAgain",
|
|
|
|
mFindBackwards? upStr.get(): dnStr.get());
|
|
|
|
windowSupportsData->GetData(getter_AddRefs(searchWindowSupports));
|
|
|
|
// findnext performed if search window data cleared out
|
2012-07-30 07:20:58 -07:00
|
|
|
*outDidFind = searchWindowSupports == nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (*outDidFind)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// next, look in the current frame. If found, return.
|
2008-02-28 07:28:37 -08:00
|
|
|
|
|
|
|
// Beware! This may flush notifications via synchronous
|
|
|
|
// ScrollSelectionIntoView.
|
2011-10-17 07:59:28 -07:00
|
|
|
rv = SearchInFrame(searchFrame, false, outDidFind);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (*outDidFind)
|
|
|
|
return OnFind(searchFrame); // we are done
|
|
|
|
|
|
|
|
// if we are not searching other frames, return
|
|
|
|
if (!mSearchSubFrames && !mSearchParentFrames)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
nsIDocShell *rootDocShell = GetDocShellFromWindow(rootFrame);
|
|
|
|
if (!rootDocShell) return NS_ERROR_FAILURE;
|
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
int32_t enumDirection;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (mFindBackwards)
|
|
|
|
enumDirection = nsIDocShell::ENUMERATE_BACKWARDS;
|
|
|
|
else
|
|
|
|
enumDirection = nsIDocShell::ENUMERATE_FORWARDS;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> docShellEnumerator;
|
|
|
|
rv = rootDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeAll,
|
|
|
|
enumDirection, getter_AddRefs(docShellEnumerator));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// remember where we started
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> startingItem =
|
|
|
|
do_QueryInterface(GetDocShellFromWindow(searchFrame), &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> curItem;
|
|
|
|
|
|
|
|
// XXX We should avoid searching in frameset documents here.
|
|
|
|
// We also need to honour mSearchSubFrames and mSearchParentFrames.
|
2011-09-28 23:19:26 -07:00
|
|
|
bool hasMore, doFind = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMore)) && hasMore)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsISupports> curSupports;
|
|
|
|
rv = docShellEnumerator->GetNext(getter_AddRefs(curSupports));
|
|
|
|
if (NS_FAILED(rv)) break;
|
|
|
|
curItem = do_QueryInterface(curSupports, &rv);
|
|
|
|
if (NS_FAILED(rv)) break;
|
|
|
|
|
|
|
|
if (doFind)
|
|
|
|
{
|
2014-01-09 18:03:47 -08:00
|
|
|
searchFrame = curItem->GetWindow();
|
|
|
|
if (!searchFrame) {
|
|
|
|
break;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
OnStartSearchFrame(searchFrame);
|
|
|
|
|
2008-02-28 07:28:37 -08:00
|
|
|
// Beware! This may flush notifications via synchronous
|
|
|
|
// ScrollSelectionIntoView.
|
2011-10-17 07:59:28 -07:00
|
|
|
rv = SearchInFrame(searchFrame, false, outDidFind);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (*outDidFind)
|
|
|
|
return OnFind(searchFrame); // we are done
|
|
|
|
|
|
|
|
OnEndSearchFrame(searchFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (curItem.get() == startingItem.get())
|
2011-10-17 07:59:28 -07:00
|
|
|
doFind = true; // start looking in frames after this one
|
2007-03-22 10:30:00 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
if (!mWrapFind)
|
|
|
|
{
|
|
|
|
// remember where we left off
|
|
|
|
SetCurrentSearchFrame(searchFrame);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// From here on, we're wrapping, first through the other frames,
|
|
|
|
// then finally from the beginning of the starting frame back to
|
|
|
|
// the starting point.
|
|
|
|
|
|
|
|
// because nsISimpleEnumerator is totally lame and isn't resettable, I
|
|
|
|
// have to make a new one
|
2012-07-30 07:20:58 -07:00
|
|
|
docShellEnumerator = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
rv = rootDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeAll,
|
|
|
|
enumDirection, getter_AddRefs(docShellEnumerator));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMore)) && hasMore)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsISupports> curSupports;
|
|
|
|
rv = docShellEnumerator->GetNext(getter_AddRefs(curSupports));
|
|
|
|
if (NS_FAILED(rv)) break;
|
|
|
|
curItem = do_QueryInterface(curSupports, &rv);
|
|
|
|
if (NS_FAILED(rv)) break;
|
|
|
|
|
2014-01-09 18:03:47 -08:00
|
|
|
searchFrame = curItem->GetWindow();
|
|
|
|
if (!searchFrame) {
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
break;
|
|
|
|
}
|
2012-10-18 06:18:30 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
if (curItem.get() == startingItem.get())
|
|
|
|
{
|
2008-02-28 07:28:37 -08:00
|
|
|
// Beware! This may flush notifications via synchronous
|
|
|
|
// ScrollSelectionIntoView.
|
2011-10-17 07:59:28 -07:00
|
|
|
rv = SearchInFrame(searchFrame, true, outDidFind);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (*outDidFind)
|
|
|
|
return OnFind(searchFrame); // we are done
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
OnStartSearchFrame(searchFrame);
|
|
|
|
|
2008-02-28 07:28:37 -08:00
|
|
|
// Beware! This may flush notifications via synchronous
|
|
|
|
// ScrollSelectionIntoView.
|
2011-10-17 07:59:28 -07:00
|
|
|
rv = SearchInFrame(searchFrame, false, outDidFind);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (*outDidFind)
|
|
|
|
return OnFind(searchFrame); // we are done
|
|
|
|
|
|
|
|
OnEndSearchFrame(searchFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// remember where we left off
|
|
|
|
SetCurrentSearchFrame(searchFrame);
|
|
|
|
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Something failed");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* attribute wstring searchString; */
|
2014-01-04 07:02:17 -08:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetSearchString(char16_t * *aSearchString)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aSearchString);
|
|
|
|
*aSearchString = ToNewUnicode(mSearchString);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-01-04 07:02:17 -08:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetSearchString(const char16_t * aSearchString)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
mSearchString.Assign(aSearchString);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute boolean findBackwards; */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetFindBackwards(bool *aFindBackwards)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aFindBackwards);
|
|
|
|
*aFindBackwards = mFindBackwards;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetFindBackwards(bool aFindBackwards)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
mFindBackwards = aFindBackwards;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute boolean wrapFind; */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetWrapFind(bool *aWrapFind)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aWrapFind);
|
|
|
|
*aWrapFind = mWrapFind;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetWrapFind(bool aWrapFind)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
mWrapFind = aWrapFind;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute boolean entireWord; */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetEntireWord(bool *aEntireWord)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aEntireWord);
|
|
|
|
*aEntireWord = mEntireWord;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetEntireWord(bool aEntireWord)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
mEntireWord = aEntireWord;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute boolean matchCase; */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetMatchCase(bool *aMatchCase)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aMatchCase);
|
|
|
|
*aMatchCase = mMatchCase;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetMatchCase(bool aMatchCase)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
mMatchCase = aMatchCase;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
IsInNativeAnonymousSubtree(nsIContent* aContent)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
while (aContent) {
|
|
|
|
nsIContent* bindingParent = aContent->GetBindingParent();
|
|
|
|
if (bindingParent == aContent) {
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
aContent = bindingParent;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsWebBrowserFind::SetSelectionAndScroll(nsIDOMWindow* aWindow,
|
|
|
|
nsIDOMRange* aRange)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
|
|
aWindow->GetDocument(getter_AddRefs(domDoc));
|
|
|
|
if (!domDoc) return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
2010-06-25 06:59:57 -07:00
|
|
|
nsIPresShell* presShell = doc->GetShell();
|
2007-03-22 10:30:00 -07:00
|
|
|
if (!presShell) return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
aRange->GetStartContainer(getter_AddRefs(node));
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
2009-12-24 13:20:06 -08:00
|
|
|
nsIFrame* frame = content->GetPrimaryFrame();
|
2007-11-18 10:53:43 -08:00
|
|
|
if (!frame)
|
|
|
|
return;
|
|
|
|
nsCOMPtr<nsISelectionController> selCon;
|
|
|
|
frame->GetSelectionController(presShell->GetPresContext(),
|
|
|
|
getter_AddRefs(selCon));
|
|
|
|
|
|
|
|
// since the match could be an anonymous textnode inside a
|
|
|
|
// <textarea> or text <input>, we need to get the outer frame
|
2012-07-30 07:20:58 -07:00
|
|
|
nsITextControlFrame *tcFrame = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
for ( ; content; content = content->GetParent()) {
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
if (!IsInNativeAnonymousSubtree(content)) {
|
2009-12-24 13:20:06 -08:00
|
|
|
nsIFrame* f = content->GetPrimaryFrame();
|
2007-11-18 10:53:43 -08:00
|
|
|
if (!f)
|
2007-03-22 10:30:00 -07:00
|
|
|
return;
|
2009-01-12 11:20:59 -08:00
|
|
|
tcFrame = do_QueryFrame(f);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsISelection> selection;
|
|
|
|
|
|
|
|
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
|
|
|
|
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
|
|
|
getter_AddRefs(selection));
|
|
|
|
if (selection) {
|
|
|
|
selection->RemoveAllRanges();
|
|
|
|
selection->AddRange(aRange);
|
|
|
|
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
|
|
|
|
if (fm) {
|
|
|
|
if (tcFrame) {
|
|
|
|
nsCOMPtr<nsIDOMElement> newFocusedElement(do_QueryInterface(content));
|
|
|
|
fm->SetFocus(newFocusedElement, nsIFocusManager::FLAG_NOSCROLL);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsCOMPtr<nsIDOMElement> result;
|
2012-07-30 07:20:58 -07:00
|
|
|
fm->MoveFocus(aWindow, nullptr, nsIFocusManager::MOVEFOCUS_CARET,
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
nsIFocusManager::FLAG_NOSCROLL,
|
|
|
|
getter_AddRefs(result));
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Scroll if necessary to make the selection visible:
|
|
|
|
// Must be the last thing to do - bug 242056
|
2008-02-28 07:28:37 -08:00
|
|
|
|
|
|
|
// After ScrollSelectionIntoView(), the pending notifications might be
|
|
|
|
// flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
|
2007-03-22 10:30:00 -07:00
|
|
|
selCon->ScrollSelectionIntoView
|
|
|
|
(nsISelectionController::SELECTION_NORMAL,
|
2010-11-24 17:35:02 -08:00
|
|
|
nsISelectionController::SELECTION_WHOLE_SELECTION,
|
2012-04-26 12:04:33 -07:00
|
|
|
nsISelectionController::SCROLL_CENTER_VERTICALLY |
|
2010-10-21 13:56:20 -07:00
|
|
|
nsISelectionController::SCROLL_SYNCHRONOUS);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adapted from nsTextServicesDocument::GetDocumentContentRootNode
|
|
|
|
nsresult nsWebBrowserFind::GetRootNode(nsIDOMDocument* aDomDoc,
|
|
|
|
nsIDOMNode **aNode)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
|
|
*aNode = 0;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(aDomDoc);
|
|
|
|
if (htmlDoc)
|
|
|
|
{
|
|
|
|
// For HTML documents, the content root node is the body.
|
|
|
|
nsCOMPtr<nsIDOMHTMLElement> bodyElement;
|
|
|
|
rv = htmlDoc->GetBody(getter_AddRefs(bodyElement));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
NS_ENSURE_ARG_POINTER(bodyElement);
|
|
|
|
return bodyElement->QueryInterface(NS_GET_IID(nsIDOMNode),
|
|
|
|
(void **)aNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
// For non-HTML documents, the content root node will be the doc element.
|
|
|
|
nsCOMPtr<nsIDOMElement> docElement;
|
|
|
|
rv = aDomDoc->GetDocumentElement(getter_AddRefs(docElement));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
NS_ENSURE_ARG_POINTER(docElement);
|
|
|
|
return docElement->QueryInterface(NS_GET_IID(nsIDOMNode), (void **)aNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsWebBrowserFind::SetRangeAroundDocument(nsIDOMRange* aSearchRange,
|
|
|
|
nsIDOMRange* aStartPt,
|
|
|
|
nsIDOMRange* aEndPt,
|
|
|
|
nsIDOMDocument* aDoc)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode> bodyNode;
|
|
|
|
nsresult rv = GetRootNode(aDoc, getter_AddRefs(bodyNode));
|
|
|
|
nsCOMPtr<nsIContent> bodyContent (do_QueryInterface(bodyNode));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
NS_ENSURE_ARG_POINTER(bodyContent);
|
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t childCount = bodyContent->GetChildCount();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
aSearchRange->SetStart(bodyNode, 0);
|
|
|
|
aSearchRange->SetEnd(bodyNode, childCount);
|
|
|
|
|
|
|
|
if (mFindBackwards)
|
|
|
|
{
|
|
|
|
aStartPt->SetStart(bodyNode, childCount);
|
|
|
|
aStartPt->SetEnd(bodyNode, childCount);
|
|
|
|
aEndPt->SetStart(bodyNode, 0);
|
|
|
|
aEndPt->SetEnd(bodyNode, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aStartPt->SetStart(bodyNode, 0);
|
|
|
|
aStartPt->SetEnd(bodyNode, 0);
|
|
|
|
aEndPt->SetStart(bodyNode, childCount);
|
|
|
|
aEndPt->SetEnd(bodyNode, childCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the range to go from the end of the current selection to the
|
|
|
|
// end of the document (forward), or beginning to beginning (reverse).
|
|
|
|
// or around the whole document if there's no selection.
|
|
|
|
nsresult
|
|
|
|
nsWebBrowserFind::GetSearchLimits(nsIDOMRange* aSearchRange,
|
|
|
|
nsIDOMRange* aStartPt,
|
|
|
|
nsIDOMRange* aEndPt,
|
|
|
|
nsIDOMDocument* aDoc,
|
|
|
|
nsISelection* aSel,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool aWrap)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aSel);
|
|
|
|
|
|
|
|
// There is a selection.
|
2012-08-22 08:56:38 -07:00
|
|
|
int32_t count = -1;
|
2007-03-22 10:30:00 -07:00
|
|
|
nsresult rv = aSel->GetRangeCount(&count);
|
2013-01-15 14:52:42 -08:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (count < 1)
|
|
|
|
return SetRangeAroundDocument(aSearchRange, aStartPt, aEndPt, aDoc);
|
|
|
|
|
|
|
|
// Need bodyNode, for the start/end of the document
|
|
|
|
nsCOMPtr<nsIDOMNode> bodyNode;
|
|
|
|
rv = GetRootNode(aDoc, getter_AddRefs(bodyNode));
|
2013-01-15 14:52:42 -08:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIContent> bodyContent (do_QueryInterface(bodyNode));
|
|
|
|
NS_ENSURE_ARG_POINTER(bodyContent);
|
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t childCount = bodyContent->GetChildCount();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// There are four possible range endpoints we might use:
|
|
|
|
// DocumentStart, SelectionStart, SelectionEnd, DocumentEnd.
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMRange> range;
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
2012-08-22 08:56:38 -07:00
|
|
|
int32_t offset;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Forward, not wrapping: SelEnd to DocEnd
|
|
|
|
if (!mFindBackwards && !aWrap)
|
|
|
|
{
|
|
|
|
// This isn't quite right, since the selection's ranges aren't
|
|
|
|
// necessarily in order; but they usually will be.
|
|
|
|
aSel->GetRangeAt(count-1, getter_AddRefs(range));
|
|
|
|
if (!range) return NS_ERROR_UNEXPECTED;
|
|
|
|
range->GetEndContainer(getter_AddRefs(node));
|
|
|
|
if (!node) return NS_ERROR_UNEXPECTED;
|
|
|
|
range->GetEndOffset(&offset);
|
|
|
|
|
|
|
|
aSearchRange->SetStart(node, offset);
|
|
|
|
aSearchRange->SetEnd(bodyNode, childCount);
|
|
|
|
aStartPt->SetStart(node, offset);
|
|
|
|
aStartPt->SetEnd(node, offset);
|
|
|
|
aEndPt->SetStart(bodyNode, childCount);
|
|
|
|
aEndPt->SetEnd(bodyNode, childCount);
|
|
|
|
}
|
|
|
|
// Backward, not wrapping: DocStart to SelStart
|
|
|
|
else if (mFindBackwards && !aWrap)
|
|
|
|
{
|
|
|
|
aSel->GetRangeAt(0, getter_AddRefs(range));
|
|
|
|
if (!range) return NS_ERROR_UNEXPECTED;
|
|
|
|
range->GetStartContainer(getter_AddRefs(node));
|
|
|
|
if (!node) return NS_ERROR_UNEXPECTED;
|
|
|
|
range->GetStartOffset(&offset);
|
|
|
|
|
|
|
|
aSearchRange->SetStart(bodyNode, 0);
|
|
|
|
aSearchRange->SetEnd(bodyNode, childCount);
|
|
|
|
aStartPt->SetStart(node, offset);
|
|
|
|
aStartPt->SetEnd(node, offset);
|
|
|
|
aEndPt->SetStart(bodyNode, 0);
|
|
|
|
aEndPt->SetEnd(bodyNode, 0);
|
|
|
|
}
|
|
|
|
// Forward, wrapping: DocStart to SelEnd
|
|
|
|
else if (!mFindBackwards && aWrap)
|
|
|
|
{
|
|
|
|
aSel->GetRangeAt(count-1, getter_AddRefs(range));
|
|
|
|
if (!range) return NS_ERROR_UNEXPECTED;
|
|
|
|
range->GetEndContainer(getter_AddRefs(node));
|
|
|
|
if (!node) return NS_ERROR_UNEXPECTED;
|
|
|
|
range->GetEndOffset(&offset);
|
|
|
|
|
|
|
|
aSearchRange->SetStart(bodyNode, 0);
|
|
|
|
aSearchRange->SetEnd(bodyNode, childCount);
|
|
|
|
aStartPt->SetStart(bodyNode, 0);
|
|
|
|
aStartPt->SetEnd(bodyNode, 0);
|
|
|
|
aEndPt->SetStart(node, offset);
|
|
|
|
aEndPt->SetEnd(node, offset);
|
|
|
|
}
|
|
|
|
// Backward, wrapping: SelStart to DocEnd
|
|
|
|
else if (mFindBackwards && aWrap)
|
|
|
|
{
|
|
|
|
aSel->GetRangeAt(0, getter_AddRefs(range));
|
|
|
|
if (!range) return NS_ERROR_UNEXPECTED;
|
|
|
|
range->GetStartContainer(getter_AddRefs(node));
|
|
|
|
if (!node) return NS_ERROR_UNEXPECTED;
|
|
|
|
range->GetStartOffset(&offset);
|
|
|
|
|
|
|
|
aSearchRange->SetStart(bodyNode, 0);
|
|
|
|
aSearchRange->SetEnd(bodyNode, childCount);
|
|
|
|
aStartPt->SetStart(bodyNode, childCount);
|
|
|
|
aStartPt->SetEnd(bodyNode, childCount);
|
|
|
|
aEndPt->SetStart(node, offset);
|
|
|
|
aEndPt->SetEnd(node, offset);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute boolean searchFrames; */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetSearchFrames(bool *aSearchFrames)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aSearchFrames);
|
|
|
|
// this only returns true if we are searching both sub and parent
|
|
|
|
// frames. There is ambiguity if the caller has previously set
|
|
|
|
// one, but not both of these.
|
|
|
|
*aSearchFrames = mSearchSubFrames && mSearchParentFrames;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetSearchFrames(bool aSearchFrames)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
mSearchSubFrames = aSearchFrames;
|
|
|
|
mSearchParentFrames = aSearchFrames;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute nsIDOMWindow currentSearchFrame; */
|
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetCurrentSearchFrame(nsIDOMWindow * *aCurrentSearchFrame)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aCurrentSearchFrame);
|
|
|
|
nsCOMPtr<nsIDOMWindow> searchFrame = do_QueryReferent(mCurrentSearchFrame);
|
|
|
|
NS_IF_ADDREF(*aCurrentSearchFrame = searchFrame);
|
|
|
|
return (*aCurrentSearchFrame) ? NS_OK : NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetCurrentSearchFrame(nsIDOMWindow * aCurrentSearchFrame)
|
|
|
|
{
|
|
|
|
// is it ever valid to set this to null?
|
|
|
|
NS_ENSURE_ARG(aCurrentSearchFrame);
|
|
|
|
mCurrentSearchFrame = do_GetWeakReference(aCurrentSearchFrame);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute nsIDOMWindow rootSearchFrame; */
|
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetRootSearchFrame(nsIDOMWindow * *aRootSearchFrame)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aRootSearchFrame);
|
|
|
|
nsCOMPtr<nsIDOMWindow> searchFrame = do_QueryReferent(mRootSearchFrame);
|
|
|
|
NS_IF_ADDREF(*aRootSearchFrame = searchFrame);
|
|
|
|
return (*aRootSearchFrame) ? NS_OK : NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetRootSearchFrame(nsIDOMWindow * aRootSearchFrame)
|
|
|
|
{
|
|
|
|
// is it ever valid to set this to null?
|
|
|
|
NS_ENSURE_ARG(aRootSearchFrame);
|
|
|
|
mRootSearchFrame = do_GetWeakReference(aRootSearchFrame);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute boolean searchSubframes; */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetSearchSubframes(bool *aSearchSubframes)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aSearchSubframes);
|
|
|
|
*aSearchSubframes = mSearchSubFrames;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetSearchSubframes(bool aSearchSubframes)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
mSearchSubFrames = aSearchSubframes;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute boolean searchParentFrames; */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::GetSearchParentFrames(bool *aSearchParentFrames)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aSearchParentFrames);
|
|
|
|
*aSearchParentFrames = mSearchParentFrames;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP nsWebBrowserFind::SetSearchParentFrames(bool aSearchParentFrames)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
mSearchParentFrames = aSearchParentFrames;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
This method handles finding in a single window (aka frame).
|
|
|
|
|
|
|
|
*/
|
|
|
|
nsresult nsWebBrowserFind::SearchInFrame(nsIDOMWindow* aWindow,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool aWrapping,
|
|
|
|
bool* aDidFind)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG(aWindow);
|
|
|
|
NS_ENSURE_ARG_POINTER(aDidFind);
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
*aDidFind = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
|
|
nsresult rv = aWindow->GetDocument(getter_AddRefs(domDoc));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!domDoc) return NS_ERROR_FAILURE;
|
|
|
|
|
2007-07-09 21:14:00 -07:00
|
|
|
// Do security check, to ensure that the frame we're searching is
|
|
|
|
// acccessible from the frame where the Find is being run.
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// get a uri for the window
|
|
|
|
nsCOMPtr<nsIDocument> theDoc = do_QueryInterface(domDoc);
|
|
|
|
if (!theDoc) return NS_ERROR_FAILURE;
|
|
|
|
|
2014-05-13 02:58:00 -07:00
|
|
|
if (!nsContentUtils::SubjectPrincipal()->Subsumes(theDoc->NodePrincipal())) {
|
2014-05-06 15:43:03 -07:00
|
|
|
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-02-21 15:13:24 -08:00
|
|
|
nsCOMPtr<nsIFind> find = do_CreateInstance(NS_FIND_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-02-21 15:13:24 -08:00
|
|
|
(void) find->SetCaseSensitive(mMatchCase);
|
|
|
|
(void) find->SetFindBackwards(mFindBackwards);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// XXX Make and set a line breaker here, once that's implemented.
|
2012-02-21 15:13:24 -08:00
|
|
|
(void) find->SetWordBreaker(0);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Now make sure the content (for actual finding) and frame (for
|
|
|
|
// selection) models are up to date.
|
|
|
|
theDoc->FlushPendingNotifications(Flush_Frames);
|
|
|
|
|
|
|
|
nsCOMPtr<nsISelection> sel;
|
|
|
|
GetFrameSelection(aWindow, getter_AddRefs(sel));
|
|
|
|
NS_ENSURE_ARG_POINTER(sel);
|
|
|
|
|
2013-02-07 04:09:41 -08:00
|
|
|
nsCOMPtr<nsIDOMRange> searchRange = nsFind::CreateRange(theDoc);
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_ARG_POINTER(searchRange);
|
2013-02-07 04:09:41 -08:00
|
|
|
nsCOMPtr<nsIDOMRange> startPt = nsFind::CreateRange(theDoc);
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_ARG_POINTER(startPt);
|
2013-02-07 04:09:41 -08:00
|
|
|
nsCOMPtr<nsIDOMRange> endPt = nsFind::CreateRange(theDoc);
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_ARG_POINTER(endPt);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMRange> foundRange;
|
|
|
|
|
|
|
|
// If !aWrapping, search from selection to end
|
|
|
|
if (!aWrapping)
|
|
|
|
rv = GetSearchLimits(searchRange, startPt, endPt, domDoc, sel,
|
2011-10-17 07:59:28 -07:00
|
|
|
false);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// If aWrapping, search the part of the starting frame
|
|
|
|
// up to the point where we left off.
|
|
|
|
else
|
|
|
|
rv = GetSearchLimits(searchRange, startPt, endPt, domDoc, sel,
|
2011-10-17 07:59:28 -07:00
|
|
|
true);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2012-02-21 15:13:24 -08:00
|
|
|
rv = find->Find(mSearchString.get(), searchRange, startPt, endPt,
|
|
|
|
getter_AddRefs(foundRange));
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv) && foundRange)
|
|
|
|
{
|
2011-10-17 07:59:28 -07:00
|
|
|
*aDidFind = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
sel->RemoveAllRanges();
|
2008-02-28 07:28:37 -08:00
|
|
|
// Beware! This may flush notifications via synchronous
|
|
|
|
// ScrollSelectionIntoView.
|
2007-03-22 10:30:00 -07:00
|
|
|
SetSelectionAndScroll(aWindow, foundRange);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// called when we start searching a frame that is not the initial
|
|
|
|
// focussed frame. Prepare the frame to be searched.
|
|
|
|
// we clear the selection, so that the search starts from the top
|
|
|
|
// of the frame.
|
|
|
|
nsresult nsWebBrowserFind::OnStartSearchFrame(nsIDOMWindow *aWindow)
|
|
|
|
{
|
|
|
|
return ClearFrameSelection(aWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
// called when we are done searching a frame and didn't find anything,
|
|
|
|
// and about about to start searching the next frame.
|
|
|
|
nsresult nsWebBrowserFind::OnEndSearchFrame(nsIDOMWindow *aWindow)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsWebBrowserFind::GetFrameSelection(nsIDOMWindow* aWindow,
|
|
|
|
nsISelection** aSel)
|
|
|
|
{
|
2012-07-30 07:20:58 -07:00
|
|
|
*aSel = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
|
|
aWindow->GetDocument(getter_AddRefs(domDoc));
|
|
|
|
if (!domDoc) return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
2010-06-25 06:59:57 -07:00
|
|
|
nsIPresShell* presShell = doc->GetShell();
|
2007-03-22 10:30:00 -07:00
|
|
|
if (!presShell) return;
|
|
|
|
|
|
|
|
// text input controls have their independent selection controllers
|
|
|
|
// that we must use when they have focus.
|
|
|
|
nsPresContext *presContext = presShell->GetPresContext();
|
|
|
|
|
2012-10-18 06:18:30 -07:00
|
|
|
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow));
|
|
|
|
|
|
|
|
nsCOMPtr<nsPIDOMWindow> focusedWindow;
|
|
|
|
nsCOMPtr<nsIContent> focusedContent =
|
|
|
|
nsFocusManager::GetFocusedDescendant(window, false, getter_AddRefs(focusedWindow));
|
|
|
|
|
|
|
|
nsIFrame *frame = focusedContent ? focusedContent->GetPrimaryFrame() : nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsISelectionController> selCon;
|
|
|
|
if (frame) {
|
|
|
|
frame->GetSelectionController(presContext, getter_AddRefs(selCon));
|
|
|
|
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSel);
|
|
|
|
if (*aSel) {
|
2012-08-22 08:56:38 -07:00
|
|
|
int32_t count = -1;
|
2007-03-22 10:30:00 -07:00
|
|
|
(*aSel)->GetRangeCount(&count);
|
|
|
|
if (count > 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
NS_RELEASE(*aSel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
selCon = do_QueryInterface(presShell);
|
|
|
|
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSel);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsWebBrowserFind::ClearFrameSelection(nsIDOMWindow *aWindow)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG(aWindow);
|
|
|
|
nsCOMPtr<nsISelection> selection;
|
|
|
|
GetFrameSelection(aWindow, getter_AddRefs(selection));
|
|
|
|
if (selection)
|
|
|
|
selection->RemoveAllRanges();
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsWebBrowserFind::OnFind(nsIDOMWindow *aFoundWindow)
|
|
|
|
{
|
|
|
|
SetCurrentSearchFrame(aFoundWindow);
|
|
|
|
|
|
|
|
// We don't want a selection to appear in two frames simultaneously
|
|
|
|
nsCOMPtr<nsIDOMWindow> lastFocusedWindow = do_QueryReferent(mLastFocusedWindow);
|
|
|
|
if (lastFocusedWindow && lastFocusedWindow != aFoundWindow)
|
|
|
|
ClearFrameSelection(lastFocusedWindow);
|
|
|
|
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
|
|
|
|
if (fm) {
|
|
|
|
// get the containing frame and focus it. For top-level windows,
|
|
|
|
// the right window should already be focused.
|
|
|
|
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aFoundWindow));
|
|
|
|
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
|
|
|
|
2013-07-23 16:39:17 -07:00
|
|
|
nsCOMPtr<nsIDOMElement> frameElement =
|
|
|
|
do_QueryInterface(window->GetFrameElementInternal());
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 11:00:39 -07:00
|
|
|
if (frameElement)
|
|
|
|
fm->SetFocus(frameElement, 0);
|
|
|
|
|
|
|
|
mLastFocusedWindow = do_GetWeakReference(aFoundWindow);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
GetDocShellFromWindow
|
|
|
|
|
2012-07-30 07:20:58 -07:00
|
|
|
Utility method. This will always return nullptr if no docShell
|
2007-03-22 10:30:00 -07:00
|
|
|
is returned. Oh why isn't there a better way to do this?
|
|
|
|
----------------------------------------------------------------------------*/
|
|
|
|
nsIDocShell *
|
|
|
|
nsWebBrowserFind::GetDocShellFromWindow(nsIDOMWindow *inWindow)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(inWindow));
|
2012-07-30 07:20:58 -07:00
|
|
|
if (!window) return nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return window->GetDocShell();
|
|
|
|
}
|
|
|
|
|