Add window.find(). Bug 9550. Patch from Fabian <hidday@geocities.com>,

r=sfraser, sr=jst


git-svn-id: svn://10.0.0.236/trunk@104267 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzbarsky%mit.edu 2001-09-30 19:56:32 +00:00
parent 32927773ec
commit 56a9af87d4
6 changed files with 204 additions and 6 deletions

View File

@ -83,4 +83,16 @@ interface nsIDOMJSWindow : nsISupports
*/
readonly attribute nsIDOMWindow frames;
/* Scriptable version of find(). See nsIDOMWindowInternal for the
* non-scriptable version. It takes 7 optional arguments:
* @param searchString: the search string
* @param caseSensitive: is the search case sensitive?
* @param backwards: should we search backwards?
* @param wrapAround: should wrap the search?
* @param wholeWord: should we search only for whole words?
* @param searchInFrames: should we search in all frames?
* @param showDialog: should we show the Find Dialog?
*/
boolean find();
};

View File

@ -161,4 +161,21 @@ interface nsIDOMWindowInternal : nsIDOMWindow
DOMString escape(in DOMString str);
DOMString unescape(in DOMString str);
/* See nsIDOMJSWindow for the scriptable version of find()
* @param str: the search pattern
* @param caseSensitive: is the search caseSensitive
* @param backwards: should we search backwards
* @param wrapAround: should we wrap the search
* @param wholeWord: should we search only for whole words
* @param searchInFrames: should we search through all frames
* @param showDialog: should we show the Find dialog
*/
[noscript] boolean find(in DOMString str,
in boolean caseSensitive,
in boolean backwards,
in boolean wrapAround,
in boolean wholeWord,
in boolean searchInFrames,
in boolean showDialog);
};

View File

@ -109,7 +109,9 @@
#include "nsIWebNavigation.h"
#include "nsIWebBrowser.h"
#include "nsIWebBrowserChrome.h"
#include "nsIWebBrowserFind.h" // For window.find()
#include "nsIWebShell.h"
#include "nsIWindowMediator.h" // For window.find()
#include "nsIComputedDOMStyle.h"
#include "nsIEntropyCollector.h"
#include "nsDOMCID.h"
@ -144,6 +146,7 @@ static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
static NS_DEFINE_CID(kCharsetConverterManagerCID,
NS_ICHARSETCONVERTERMANAGER_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); // For window.find()
static const char *sWindowWatcherContractID = "@mozilla.org/embedcomp/window-watcher;1";
static const char *sJSStackContractID = "@mozilla.org/js/xpc/ContextStack;1";
@ -2649,6 +2652,161 @@ NS_IMETHODIMP GlobalWindowImpl::GetSelection(nsISelection** aSelection)
aSelection);
}
// Non-scriptable version of window.find(), part of nsIDOMWindowInternal
NS_IMETHODIMP
GlobalWindowImpl::Find(const nsAReadableString& aStr,
PRBool aCaseSensitive,
PRBool aBackwards,
PRBool aWrapAround,
PRBool aWholeWord,
PRBool aSearchInFrames,
PRBool aShowDialog,
PRBool *aDidFind)
{
return FindInternal(aStr, aCaseSensitive, aBackwards, aWrapAround,
aWholeWord, aSearchInFrames, aShowDialog, aDidFind);
}
// Scriptable version of window.find() which takes a variable number of
// arguments, part of nsIDOMJSWindow.
NS_IMETHODIMP
GlobalWindowImpl::Find(PRBool *aDidFind)
{
NS_ENSURE_STATE(sXPConnect);
nsresult rv = NS_OK;
// We get the arguments passed to the function using the XPConnect native
// call context.
nsCOMPtr<nsIXPCNativeCallContext> ncc;
rv = sXPConnect->GetCurrentNativeCallContext(getter_AddRefs(ncc));
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(ncc, "No Native Call Context."
"Please don't call this method from C++.");
if (!ncc) {
return NS_ERROR_NOT_AVAILABLE;
}
JSContext *cx = nsnull;
rv = ncc->GetJSContext(&cx);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 argc;
jsval *argv = nsnull;
ncc->GetArgc(&argc);
ncc->GetArgvPtr(&argv);
// Parse the arguments passed to the function
nsAutoString searchStr;
PRBool caseSensitive = PR_FALSE;
PRBool backwards = PR_FALSE;
PRBool wrapAround = PR_FALSE;
PRBool showDialog = PR_FALSE;
PRBool wholeWord = PR_FALSE;
PRBool searchInFrames = PR_FALSE;
if (argc > 0) {
// First arg is the search pattern
nsJSUtils::ConvertJSValToString(searchStr, cx, argv[0]);
}
if (argc > 1 && !JS_ValueToBoolean(cx, argv[1], &caseSensitive)) {
// Second arg is the case sensitivity
caseSensitive = PR_FALSE;
}
if (argc > 2 && !JS_ValueToBoolean(cx, argv[2], &backwards)) {
// Third arg specifies whether to search backwards
backwards = PR_FALSE;
}
if (argc > 3 && !JS_ValueToBoolean(cx, argv[3], &wrapAround)) {
// Fourth arg specifies whether we should wrap the search
wrapAround = PR_FALSE;
}
if (argc > 4 && !JS_ValueToBoolean(cx, argv[4], &wholeWord)) {
// Fifth arg specifies whether we should show the Find dialog
wholeWord = PR_FALSE;
}
if (argc > 5 && !JS_ValueToBoolean(cx, argv[5], &searchInFrames)) {
// Sixth arg specifies whether we should search only for whole words
searchInFrames = PR_FALSE;
}
if (argc > 6 && !JS_ValueToBoolean(cx, argv[6], &showDialog)) {
// Seventh arg specifies whether we should search in all frames
showDialog = PR_FALSE;
}
return FindInternal(searchStr, caseSensitive, backwards, wrapAround,
wholeWord, searchInFrames, showDialog, aDidFind);
}
nsresult
GlobalWindowImpl::FindInternal(nsAReadableString& aStr,
PRBool caseSensitive,
PRBool backwards,
PRBool wrapAround,
PRBool wholeWord,
PRBool searchInFrames,
PRBool showDialog,
PRBool *aDidFind)
{
NS_ENSURE_ARG_POINTER(aDidFind);
nsresult rv = NS_OK;
*aDidFind = PR_FALSE;
// GetInterface(NS_GET_IID(nsIWebBrowserFind))
nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mDocShell));
// Set the options of the search
rv = finder->SetSearchString(PromiseFlatString(aStr).get());
NS_ENSURE_SUCCESS(rv, rv);
finder->SetMatchCase(caseSensitive);
finder->SetFindBackwards(backwards);
finder->SetWrapFind(wrapAround);
finder->SetEntireWord(wholeWord);
finder->SetSearchFrames(searchInFrames);
// The Find API does not accept empty strings. Launch the Find Dialog.
if (aStr.IsEmpty() || showDialog) {
// See if the find dialog is already up using nsIWindowMediator
nsCOMPtr<nsIWindowMediator> windowMediator =
do_GetService(kWindowMediatorCID);
nsCOMPtr<nsIDOMWindowInternal> findDialog;
if (windowMediator) {
windowMediator->GetMostRecentWindow(NS_LITERAL_STRING("findInPage").get(),
getter_AddRefs(findDialog));
}
if (findDialog) {
// The Find dialog is already open, bring it to the top.
rv = findDialog->Focus();
} else { // Open a Find dialog
if (finder) {
nsCOMPtr<nsIDOMWindow> dialog;
rv = OpenDialog(NS_LITERAL_STRING("chrome://global/content/finddialog.xul"),
NS_LITERAL_STRING("_blank"),
NS_LITERAL_STRING("chrome, resizable=no, dependent=yes"),
finder, getter_AddRefs(dialog));
}
}
} else {
// Launch the search with the passed in search string
rv = finder->FindNext(aDidFind);
NS_ENSURE_SUCCESS(rv, rv);
}
return rv;
}
//*****************************************************************************
// GlobalWindowImpl::nsIDOMEventTarget
//*****************************************************************************

View File

@ -232,6 +232,12 @@ protected:
nsresult CheckSecurityWidthAndHeight(PRInt32* width, PRInt32* height);
nsresult CheckSecurityLeftAndTop(PRInt32* left, PRInt32* top);
// Helper for window.find()
nsresult FindInternal(nsAReadableString& aStr, PRBool caseSensitive,
PRBool backwards, PRBool wrapAround, PRBool wholeWord,
PRBool searchInFrames, PRBool showDialog,
PRBool *aReturn);
protected:
// When adding new member variables, be careful not to create cycles
// through JavaScript. If there is any chance that a member variable

View File

@ -55,11 +55,12 @@ function fillDialog()
var findService = Components.classes["@mozilla.org/find/find_service;1"]
.getService(Components.interfaces.nsIFindService);
// Set initial dialog field contents.
dialog.findKey.value = findService.searchString;
dialog.caseSensitive.checked = findService.matchCase;
dialog.wrap.checked = findService.wrapFind;
dialog.searchBackwards.checked = findService.findBackwards;
// Set initial dialog field contents. Use the gFindInst attributes first,
// this is necessary for window.find()
dialog.findKey.value = gFindInst.searchString ? gFindInst.searchString : findService.searchString;
dialog.caseSensitive.checked = gFindInst.matchCase ? gFindInst.matchCase : findService.matchCase;
dialog.wrap.checked = gFindInst.wrapFind ? gFindInst.wrapFind : findService.wrapFind;
dialog.searchBackwards.checked = gFindInst.findBackwards ? gFindInst.findBackwards : findService.findBackwards;
}
function saveFindData()
@ -86,7 +87,10 @@ function onLoad()
doSetOKCancel(onOK, onCancel);
// get the find instance
gFindInst = window.arguments[0];
var finder = window.arguments[0];
// If the dialog was opened from window.find(), findInst will be an
// nsISupports interface, so QueryInterface anyway to nsIWebBrowserFind.
gFindInst = finder.QueryInterface(Components.interfaces.nsIWebBrowserFind);
fillDialog();
doEnabling();

View File

@ -37,6 +37,7 @@ Contributor(s):
<window id="findDialog"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
windowtype="findInPage"
onload="onLoad();"
onunload="onUnload();"
style="width: 30em;"