Bug 167921 - allow web pages to use preventDefault so that typeaheadfind doesn't interfere with them. r=kyle, sr=brendan. Also fixes bug 165315 - typeaheadfind shouldn't hardcode kbd shortcuts, bug 77704 - add accelerator for find prev (also added menu item). Also fixes bug 167783 - ctrl+g for typeaheadfind after repeating characters. Also fixes bug 168408 - backspace after bad character typed should do the right thing, but don't add bad characters to buffer. Also fixes bug 71832 - add F3 for find next (also shift+F3). Bug 157669 - Alt+D to select location bar (IE keyboard compatibility), r=sgehani, sr=hewitt

This commit is contained in:
aaronl%netscape.com 2002-09-24 22:46:50 +00:00
parent 715b7a4466
commit d618542d85
27 changed files with 374 additions and 127 deletions

View File

@ -108,6 +108,11 @@
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectLinePrevious" />
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectLineNext" />
<!-- Supporting IE forward and back accelerators out of courtesy
to transitioning IE users -->
<handler event="keypress" keycode="VK_BACK" command="cmd_browserBack"/>
<handler event="keypress" keycode="VK_BACK" modifiers="shift" command="cmd_browserForward" />
</handlers>
</binding>

View File

@ -5874,6 +5874,8 @@ const char * const sScrollLineUpString = "cmd_scrollLineUp";
const char * const sScrollLineDownString = "cmd_scrollLineDown";
const char * const sScrollLeftString = "cmd_scrollLeft";
const char * const sScrollRightString = "cmd_scrollRight";
const char * const sBrowserBackString = "cmd_browserBack";
const char * const sBrowserForwardString = "cmd_browserForward";
// These are so the browser can use editor navigation key bindings
// helps with accessibility (boolean pref accessibility.browsewithcaret)
@ -6089,6 +6091,8 @@ nsDOMWindowController::SupportsCommand(const char * aCommand,
!nsCRT::strcmp(aCommand,sScrollPageDownString) ||
!nsCRT::strcmp(aCommand,sMovePageUpString) ||
!nsCRT::strcmp(aCommand,sMovePageDownString) ||
!nsCRT::strcmp(aCommand,sBrowserBackString) ||
!nsCRT::strcmp(aCommand,sBrowserForwardString) ||
!nsCRT::strcmp(aCommand,sScrollLineUpString) ||
!nsCRT::strcmp(aCommand,sScrollLineDownString) ||
!nsCRT::strcmp(aCommand,sScrollLeftString) ||
@ -6165,10 +6169,32 @@ nsDOMWindowController::DoCommand(const char *aCommand)
}
}
}
else if (!nsCRT::strcmp(aCommand,sBrowserBackString) ||
!nsCRT::strcmp(aCommand,sBrowserForwardString)) {
rv = DoCommandWithWebNavigationInterface(aCommand);
}
return rv;
}
nsresult
nsDOMWindowController::DoCommandWithWebNavigationInterface(const char *aCommandName)
{
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(mWindow));
nsresult rv = NS_ERROR_FAILURE;
if (webNav) {
if (!nsCRT::strcmp(aCommandName, sBrowserBackString)) {
rv = webNav->GoBack();
}
else if (!nsCRT::strcmp(aCommandName, sBrowserForwardString)) {
rv= webNav->GoForward();
}
}
return rv;
}
nsresult
nsDOMWindowController::DoCommandWithEditInterface(const char *aCommandName)
{

View File

@ -460,6 +460,7 @@ private:
nsresult GetEditInterface( nsIContentViewerEdit** aEditInterface);
nsresult GetSelectionController(nsISelectionController ** aSelCon);
nsresult DoCommandWithWebNavigationInterface(const char * aCommandName);
nsresult DoCommandWithEditInterface(const char * aCommandName);
nsresult DoCommandWithSelectionController(const char * aCommandName);

View File

@ -119,7 +119,8 @@ function SetupTextEditorCommands()
//dump("Registering plain text editor commands\n");
commandManager.registerCommand("cmd_find", nsFindCommand);
commandManager.registerCommand("cmd_findNext", nsFindNextCommand);
controller.registerCommand("cmd_findNext", new nsFindAgainCommand(false));
controller.registerCommand("cmd_findPrev", new nsFindAgainCommand(true));
commandManager.registerCommand("cmd_spelling", nsSpellingCommand);
commandManager.registerCommand("cmd_validate", nsValidateCommand);
commandManager.registerCommand("cmd_checkLinks", nsCheckLinksCommand);
@ -289,6 +290,7 @@ function noUIStateUpdateNeeded(commandID)
|| commandID == "cmd_spelling"
|| commandID == "cmd_validate"
|| commandID == "cmd_findNext"
|| commandID == "cmd_findPrev"
|| commandID == "cmd_find"
|| commandID == "cmd_preview"
|| commandID == "cmd_revert"
@ -2395,7 +2397,13 @@ var nsFindCommand =
};
//-----------------------------------------------------------------------------------
var nsFindNextCommand =
function nsFindAgainCommand(isFindPrev)
{
this.isFindPrev = isFindPrev;
}
nsFindAgainCommand.prototype =
{
isCommandEnabled: function(aCommand, dummy)
{
@ -2412,7 +2420,12 @@ var nsFindNextCommand =
try {
var editorXUL = document.getElementById("content-frame");
var findInst = editorXUL.webBrowserFind;
var findService = Components.classes["@mozilla.org/find/find_service;1"]
.getService(Components.interfaces.nsIFindService);
findInst.findBackwards = findService.findBackwards ^ this.isFindPrev;
findInst.findNext();
// reset to what it was in dialog, otherwise dialog setting can get reversed
findInst.findBackwards = findService.findBackwards;
}
catch (ex) {}
}

View File

@ -55,6 +55,9 @@
<key id="pastequotationkb" key="&editpastequotation.keybinding;" observes="cmd_pasteQuote" modifiers="accel, shift"/>
<key id="findkb" key="&editfind.keybinding;" observes="cmd_find" modifiers="accel"/>
<key id="findnextkb" key="&editfindnext.keybinding;" observes="cmd_findNext" modifiers="accel"/>
<key id="findprevkb" key="&editfindprev.keybinding;" observes="cmd_findPrev" modifiers="accel,shift"/>
<key keycode="&editfindnext.keybinding2;" observes="cmd_findNext"/>
<key keycode="&editfindprev.keybinding2;" observes="cmd_findPrev" modifiers="shift"/>
<key id="checkspellingkb" key="&editcheckspelling.keybinding;" observes="cmd_spelling" modifiers="accel" disabled="true"/>
<key id="boldkb" key="&stylebold.keybinding;" observes="cmd_bold" modifiers="accel"/>
@ -168,7 +171,8 @@
<command id="cmd_preferences" oncommand="goDoCommand('cmd_preferences')"/>
<command id="cmd_find" oncommand="goDoCommand('cmd_find')"/>
<command id="cmd_findNext" oncommand="goDoCommand('cmd_findNext')" label="&findAgainCmd.label;"/>
<command id="cmd_findNext" oncommand="goDoCommand('cmd_findNext')" label="&findAgainCmd.label;"/>
<command id="cmd_findPrev" oncommand="goDoCommand('cmd_findPrev')" label="&findPrevCmd.label;"/>
<command id="cmd_spelling" oncommand="goDoCommand('cmd_spelling')"/>
<command id="cmd_validate" label="&validateCmd.label;" accesskey="&validate.accesskey;" oncommand="goDoCommand('cmd_validate')"/>
<command id="cmd_checkLinks" oncommand="goDoCommand('cmd_checkLinks')"/>
@ -358,8 +362,9 @@
<menuseparator id="edEditMenuSep2" />
<menuitem id="menu_selectAll"/>
<menuseparator id="sep_find"/>
<menuitem id="menu_find" accesskey="&editfind.accesskey;" key="findkb" observes="cmd_find" label="&findCmd.label;"/>
<menuitem id="menu_findnext" accesskey="&editfindnext.accesskey;" key="findnextkb" observes="cmd_findNext"/>
<menuitem id="menu_find" accesskey="&editfind.accesskey;" key="findkb" observes="cmd_find" label="&findCmd.label;"/>
<menuitem id="menu_findnext" accesskey="&editfindnext.accesskey;" key="findnextkb" observes="cmd_findNext"/>
<menuitem id="menu_findprev" accesskey="&editfindprev.accesskey;" key="findprevkb" observes="cmd_findPrev"/>
<menuseparator id="sep_checkspelling"/>
<menuitem id="menu_checkspelling" accesskey="&editcheckspelling.accesskey;"
key="checkspellingkb" observes="cmd_spelling" disabled="true"

View File

@ -114,6 +114,11 @@
<!ENTITY findAgainCmd.label "Find Again">
<!ENTITY editfindnext.accesskey "g">
<!ENTITY editfindnext.keybinding "g">
<!ENTITY editfindnext.keybinding2 "VK_F3">
<!ENTITY findPrevCmd.label "Find Previous">
<!ENTITY editfindprev.accesskey "v">
<!ENTITY editfindprev.keybinding "g">
<!ENTITY editfindprev.keybinding2 "VK_F3">
<!ENTITY checkSpellingCmd.label "Check Spelling">
<!ENTITY validateCmd.label "Validate HTML">
<!ENTITY validate.accesskey "v">

View File

@ -51,6 +51,9 @@
#include "nsIDOMHTMLDocument.h"
#include "nsIContent.h"
#include "nsContentCID.h"
#include "nsIServiceManager.h"
#include "nsIObserverService.h"
#include "nsISupportsPrimitives.h"
#if DEBUG
#include "nsIWebNavigation.h"
@ -94,7 +97,25 @@ NS_IMETHODIMP nsWebBrowserFind::FindNext(PRBool *outDidFind)
nsCOMPtr<nsIDOMWindow> searchFrame = do_QueryReferent(mCurrentSearchFrame);
NS_ENSURE_TRUE(searchFrame, NS_ERROR_NOT_INITIALIZED);
// first, look in the current frame. If found, return.
// 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> observerService(do_GetService("@mozilla.org/observer-service;1"));
if (observerService) {
nsCOMPtr<nsISupportsPRBool> didExecute =
do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
didExecute->SetData(PR_FALSE);
observerService->NotifyObservers(didExecute, "nsWebBrowserFind_FindAgain", mFindBackwards? NS_L("up"): NS_L("down"));
didExecute->GetData(outDidFind);
if (*outDidFind)
return NS_OK;
}
// next, look in the current frame. If found, return.
rv = SearchInFrame(searchFrame, PR_FALSE, outDidFind);
if (NS_FAILED(rv)) return rv;
if (*outDidFind)

View File

@ -408,13 +408,13 @@ function UpdateBackForwardButtons()
forwardBroadcaster.setAttribute("disabled", !forwardDisabled);
}
function find(again)
function find(again, reverse)
{
var focusedWindow = document.commandDispatcher.focusedWindow;
if (!focusedWindow || focusedWindow == window)
focusedWindow = window._content;
if (again)
findAgainInPage(helpBrowser, window._content, focusedWindow);
findAgainInPage(helpBrowser, window._content, focusedWindow, reverse);
else
findInPage(helpBrowser, window._content, focusedWindow)
}

View File

@ -70,9 +70,13 @@
<keyset id="viewZoomKeys"/>
<keyset id="navigationKeys"/>
<key id="key_find"
key="&findOnCmd.commandkey;" oncommand="find(false);" modifiers="accel"/>
key="&findOnCmd.commandkey;" oncommand="find(false, false);" modifiers="accel"/>
<key id="key_findAgain"
key="&findAgainCmd.commandkey;" oncommand="find(true);" modifiers="accel"/>
key="&findAgainCmd.commandkey;" oncommand="find(true, false);" modifiers="accel"/>
<key id="key_findPrev"
key="&findPrevCmd.commandkey;" oncommand="find(true, true);" modifiers="accel, shift"/>
<key id="key_findAgain2" keycode="&findAgainCmd.commandkey2;" oncommand="find(true, false);" />
<key id="key_findPrev2" keycode="&findPrevCmd.commandkey2;" oncommand="find(true, true);" modifiers="shift"/>
<key id="key_viewSource" key="&pageSourceCmd.commandkey;"
oncommand="BrowserViewSource();" modifiers="accel"/>
<key id="key_viewInfo" key="&pageInfoCmd.commandkey;"

View File

@ -40,6 +40,7 @@
#include "nsISupports.idl"
#include "domstubs.idl"
#include "nsISupportsPrimitives.idl"
%{ C++
#include "nsIDOMEvent.h"
@ -66,5 +67,10 @@ interface nsITypeAheadFind : nsISupports
// it must be started manually with startNewFind()
void setAutoStart(in nsIDOMWindow aWindow, in boolean aAutoStartOn);
boolean getAutoStart(in nsIDOMWindow aWindow);
// 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.
void findNext(in boolean aReverse, in nsISupportsPRBool aDidFind);
};

View File

@ -54,6 +54,7 @@
#include "nsIDOMEventTarget.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIChromeEventHandler.h"
#include "nsIFocusController.h"
#include "nsIDOMNSEvent.h"
#include "nsIPref.h"
#include "nsString.h"
@ -168,7 +169,6 @@ nsTypeAheadFind::~nsTypeAheadFind()
nsresult
nsTypeAheadFind::Init()
{
mFindService = do_GetService("@mozilla.org/find/find_service;1");
nsresult rv = NS_NewISupportsArray(getter_AddRefs(mManualFindWindows));
NS_ENSURE_SUCCESS(rv, rv);
@ -277,6 +277,12 @@ nsTypeAheadFind::PrefsReset(const char* aPrefName, void* instance_data)
if (stringBundleService)
stringBundleService->CreateBundle(TYPEAHEADFIND_BUNDLE_URL,
getter_AddRefs(typeAheadFind->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(typeAheadFind, "nsWebBrowserFind_FindAgain", PR_TRUE);
}
}
@ -318,6 +324,12 @@ nsTypeAheadFind::Observe(nsISupports *aSubject, const char *aTopic,
else if (!nsCRT::strcmp(aTopic,"domwindowclosed")) {
isOpening = PR_FALSE;
}
else if (!nsCRT::strcmp(aTopic,"nsWebBrowserFind_FindAgain")) {
// A find next command wants to be executed.
// We might want to handle it. If we do, return true in didExecute.
nsCOMPtr<nsISupportsPRBool> didExecute(do_QueryInterface(aSubject));
return FindNext(NS_LITERAL_STRING("up").Equals(aData), didExecute);
}
else {
return NS_OK;
}
@ -561,58 +573,18 @@ nsTypeAheadFind::KeyPress(nsIDOMEvent* aEvent)
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
if (mTimer) {
mTimer->Init(this, mTimeoutLength, nsITimer::TYPE_ONE_SHOT); // Timeout from last bad key (this one)
}
StartTimeout(); // Timeout from last bad key (this one)
DisplayStatus(PR_FALSE, nsnull, PR_TRUE); // Status message to say find stopped
return NS_OK;
}
// ---------- Check the keystroke --------------------------------
if (((charCode == 'g' || charCode=='G') && isAlt + isMeta + isCtrl == 1 && (
(nsTypeAheadFind::sAccelKey == nsIDOMKeyEvent::DOM_VK_CONTROL && isCtrl) ||
(nsTypeAheadFind::sAccelKey == nsIDOMKeyEvent::DOM_VK_ALT && isAlt ) ||
(nsTypeAheadFind::sAccelKey == nsIDOMKeyEvent::DOM_VK_META && isMeta)))
#ifdef XP_MAC
// We don't use F3 for find next on Macintosh, function keys are user
// definable there
) {
#else
|| (keyCode == nsIDOMKeyEvent::DOM_VK_F3 && !isCtrl && !isMeta && !isAlt)) {
#endif
// We steal Accel+G, F3 (find next) and Accel+Shift+G, Shift+F3
// (find prev), avoid early return, so we can use our find loop
// If the global find string is different, that means it's been changed
// directly by the user, from the last type ahead find string, via the
// find dialog. In that case, let the normal find-next happen
nsAutoString globalFindString;
mFindService->GetSearchString(globalFindString);
if (globalFindString != mFindNextBuffer)
return NS_OK;
mTypeAheadBuffer = mFindNextBuffer;
if (mRepeatingMode == eRepeatingChar)
mTypeAheadBuffer = mTypeAheadBuffer.First();
mRepeatingMode = (charCode=='G' || isShift)?
eRepeatingReverse: eRepeatingForward;
mLiteralTextSearchOnly = PR_TRUE;
aEvent->PreventDefault(); // Prevent normal processing of this keystroke
}
else if ((isAlt && !isShift) || isCtrl || isMeta) {
if ((isAlt && !isShift) || isCtrl || isMeta) {
// Ignore most modified keys, but alt+shift may be used for
// entering foreign chars.
CancelFind();
return NS_OK;
}
else if (mRepeatingMode == eRepeatingForward ||
mRepeatingMode == eRepeatingReverse) {
// Once Accel+[shift]+G has been used once,
// new typing will start a new find
CancelFind();
}
PRBool isFirstVisiblePreferred = PR_FALSE;
PRBool isBackspace = PR_FALSE; // When backspace is pressed
@ -634,9 +606,8 @@ nsTypeAheadFind::KeyPress(nsIDOMEvent* aEvent)
return NS_OK;
}
// ----------- Back space ----------------------
if (keyCode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE) {
else if (keyCode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE) {
if (mTypeAheadBuffer.IsEmpty()) {
return NS_OK;
}
@ -654,16 +625,38 @@ nsTypeAheadFind::KeyPress(nsIDOMEvent* aEvent)
return NS_OK;
}
if (--mBadKeysSinceMatch < 0)
if (mBadKeysSinceMatch > 0) {
// Nothing to remove when a backspace is hit after a bad key
// because bad keys aren't added to the buffer
mBadKeysSinceMatch = 0;
mTypeAheadBuffer = Substring(mTypeAheadBuffer, 0,
mTypeAheadBuffer.Length() - 1);
}
else {
mTypeAheadBuffer.Truncate(mTypeAheadBuffer.Length() - 1);
}
isBackspace = PR_TRUE;
mDontTryExactMatch = PR_FALSE;
}
else if (keyCode) {
// Function key or some other non-printable key
return NS_OK;
}
// ----------- Printable characters --------------
else if (mRepeatingMode != eRepeatingForward &&
mRepeatingMode != eRepeatingReverse) {
else {
if (mRepeatingMode == eRepeatingForward ||
mRepeatingMode == eRepeatingReverse) {
// Once Accel+[shift]+G or [shift]+F3 has been used once,
// new typing will start a new find
CancelFind();
}
// 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;
}
PRUnichar uniChar = ToLowerCase(NS_STATIC_CAST(PRUnichar, charCode));
if (uniChar < ' ') {
@ -738,6 +731,7 @@ nsTypeAheadFind::KeyPress(nsIDOMEvent* aEvent)
presContext->GetEventStateManager(getter_AddRefs(esm));
esm->GetFocusedContent(getter_AddRefs(focusedContent));
if (focusedContent) {
mIsFindingText = PR_TRUE; // prevent selection listener from calling CancelFind()
esm->MoveCaretToFocus();
isFirstVisiblePreferred = PR_FALSE;
}
@ -745,14 +739,17 @@ nsTypeAheadFind::KeyPress(nsIDOMEvent* aEvent)
}
}
mIsFindingText = PR_TRUE; // prevent our listeners from calling CancelFind()
/*
* Find the text!
*/
aEvent->StopPropagation(); // We're using this key, no one else should
mIsFindingText = PR_TRUE; // prevent selection listener from calling CancelFind()
nsresult rv = NS_ERROR_FAILURE;
// ----------- Set search options ---------------
mFind->SetFindBackwards(mRepeatingMode == eRepeatingReverse);
if (mBadKeysSinceMatch == 0) { // Don't even try if the last key was already bad
if (mBadKeysSinceMatch <= 1) { // Don't even try if the last key was already bad
if (!mDontTryExactMatch) {
// Regular find, not repeated char find
@ -769,33 +766,13 @@ nsTypeAheadFind::KeyPress(nsIDOMEvent* aEvent)
#endif
}
aEvent->StopPropagation(); // We're using this key, no one else should
// --- If accessibility.typeaheadfind.timeout is set,
// cancel find after specified # milliseconds ---
if (mTimeoutLength) {
if (!mTimer) {
mTimer = do_CreateInstance("@mozilla.org/timer;1");
}
if (mTimer) {
mTimer->InitWithCallback(this, mTimeoutLength, nsITimer::TYPE_ONE_SHOT);
}
}
StartTimeout();
mIsFindingText = PR_FALSE;
if (NS_SUCCEEDED(rv)) {
// ------- Success!!! -----------------------------------------------------
// ------- Store current find string for regular find usage: find-next
// or find dialog text field ---------
mBadKeysSinceMatch = 0;
mFindNextBuffer = mTypeAheadBuffer;
mFindService->SetSearchString(mFindNextBuffer);
if (mRepeatingMode == eRepeatingForward ||
mRepeatingMode == eRepeatingReverse)
mTypeAheadBuffer.Truncate();
if (NS_SUCCEEDED(rv)) {
if (mTypeAheadBuffer.Length() == 1) {
// If first letter, store where the first find succeeded
// (mStartFindRange)
@ -809,14 +786,11 @@ nsTypeAheadFind::KeyPress(nsIDOMEvent* aEvent)
}
}
}
else {
if (!isBackspace)
++mBadKeysSinceMatch;
// ----- Nothing found -----
else { // ----- Nothing found -----
DisplayStatus(PR_FALSE, nsnull, PR_FALSE); // Display failure status
mRepeatingMode = eRepeatingNone;
if (!isBackspace) {
++mBadKeysSinceMatch;
// Error beep (don't been when backspace is pressed, they're
// trying to correct the mistake!)
nsCOMPtr<nsISound> soundInterface =
@ -824,23 +798,30 @@ nsTypeAheadFind::KeyPress(nsIDOMEvent* aEvent)
if (soundInterface) {
soundInterface->Beep();
}
// Remove bad character from buffer, so we can continue typing from
// last matched character
if (mTypeAheadBuffer.Length() >= 1) {
mTypeAheadBuffer.Truncate(mTypeAheadBuffer.Length() - 1);
}
}
// Remove bad character from buffer, so we can continue typing from
// last matched character
mRepeatingMode = eRepeatingNone;
}
// If first character is bad, flush it away anyway
#ifdef TYPEAHEADFIND_REMOVE_ALL_BAD_KEYS
// Remove all bad characters
if (mTypeAheadBuffer.Length() >= 1 && !isBackspace) {
#else
// Remove bad *first* characters only
if (mTypeAheadBuffer.Length() == 1 && !isBackspace) {
#endif
// Notice if () in #ifdef above!
mTypeAheadBuffer = Substring(mTypeAheadBuffer, 0,
mTypeAheadBuffer.Length() - 1);
}
// Store find string for find-next
mFindNextBuffer = mTypeAheadBuffer;
nsCOMPtr<nsIWebBrowserFind> webBrowserFind;
GetWebBrowserFind(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(mTypeAheadBuffer);
}
return NS_OK;
@ -1031,6 +1012,8 @@ nsTypeAheadFind::FindItNow(PRBool aIsRepeatingSameChar, PRBool aIsLinksOnly,
DisplayStatus(PR_TRUE, focusedContent, PR_FALSE);
mBadKeysSinceMatch = 0;
return NS_OK;
}
@ -1363,6 +1346,101 @@ nsTypeAheadFind::NotifySelectionChanged(nsIDOMDocument *aDoc,
// ---------------- nsITypeAheadFind --------------------
NS_IMETHODIMP
nsTypeAheadFind::FindNext(PRBool aFindBackwards, nsISupportsPRBool *aDidExecute)
{
NS_ENSURE_TRUE(aDidExecute, NS_ERROR_FAILURE);
aDidExecute->SetData(PR_FALSE);
if (!mIsFindAllowedInWindow || mFindNextBuffer.IsEmpty() || !mFocusedWindow) {
return NS_OK;
}
nsCOMPtr<nsPIDOMWindow> privateWindow(do_QueryInterface(mFocusedWindow));
NS_ENSURE_TRUE(privateWindow, NS_ERROR_FAILURE);
nsCOMPtr<nsIFocusController> focusController;
privateWindow->GetRootFocusController(getter_AddRefs(focusController));
NS_ENSURE_TRUE(focusController, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMWindowInternal> callerWinInternal;
focusController->GetFocusedWindow(getter_AddRefs(callerWinInternal));
nsCOMPtr<nsIDOMWindow> callerWin(do_QueryInterface(callerWinInternal));
NS_ENSURE_TRUE(callerWin, NS_ERROR_FAILURE);
nsCOMPtr<nsIPresShell> typeAheadPresShell(do_QueryReferent(mFocusedWeakShell));
NS_ENSURE_TRUE(typeAheadPresShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMDocument> callerDomDoc;
callerWin->GetDocument(getter_AddRefs(callerDomDoc));
nsCOMPtr<nsIDocument> callerDoc(do_QueryInterface(callerDomDoc));
NS_ENSURE_TRUE(callerDoc, NS_ERROR_FAILURE);
nsCOMPtr<nsIPresShell> callerPresShell;
callerDoc->GetShellAt(0, getter_AddRefs(callerPresShell));
NS_ENSURE_TRUE(callerPresShell, NS_ERROR_FAILURE);
if (callerWin != mFocusedWindow || callerPresShell != typeAheadPresShell) {
// This means typeaheadfind is active in a different window or doc
// So it's not appropriate to find next for the current window
mFindNextBuffer.Truncate();
return NS_OK;
}
nsCOMPtr<nsIWebBrowserFind> webBrowserFind;
GetWebBrowserFind(getter_AddRefs(webBrowserFind));
NS_ENSURE_TRUE(webBrowserFind, NS_ERROR_FAILURE);
nsXPIDLString webBrowserFindString;
if (webBrowserFind) {
webBrowserFind->GetSearchString(getter_Copies(webBrowserFindString));
if (!webBrowserFindString.Equals(mFindNextBuffer)) {
// If they're not equal, then the find dialog was used last,
// not typeaheadfind. Typeaheadfind applies to the last find,
// so we should let nsIWebBrowserFind::FindNext() do it.
mFindNextBuffer.Truncate();
return NS_OK;
}
}
/* -------------------------------------------------------
* Typeaheadfind is active in the currently focused window,
* so do the find next operation now
*/
aDidExecute->SetData(PR_TRUE);
if (mBadKeysSinceMatch > 0) {
// We know it will fail, so just return
return NS_OK;
}
mTypeAheadBuffer = mFindNextBuffer;
if (mRepeatingMode == eRepeatingChar)
mTypeAheadBuffer = mTypeAheadBuffer.First();
mRepeatingMode = aFindBackwards? eRepeatingReverse: eRepeatingForward;
mLiteralTextSearchOnly = PR_TRUE;
// ----------- Set search options ---------------
mFind->SetFindBackwards(aFindBackwards);
mIsFindingText = PR_TRUE; // prevent our listeners from calling CancelFind()
if (NS_FAILED(FindItNow(PR_FALSE, mLinksOnly, PR_FALSE, PR_FALSE))) {
DisplayStatus(PR_FALSE, nsnull, PR_FALSE); // Display failure status
mRepeatingMode = eRepeatingNone;
}
mTypeAheadBuffer.Truncate(); // Find buffer is now in mFindNextBuffer
StartTimeout();
mIsFindingText = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsTypeAheadFind::GetIsActive(PRBool *aIsActive)
{
@ -1548,6 +1626,41 @@ nsTypeAheadFind::CancelFind()
// ------- Helper Methods ---------------
nsresult
nsTypeAheadFind::GetWebBrowserFind(nsIWebBrowserFind **aWebBrowserFind)
{
*aWebBrowserFind = nsnull;
nsCOMPtr<nsIInterfaceRequestor> ifreq(do_QueryInterface(mFocusedWindow));
NS_ENSURE_TRUE(ifreq, NS_ERROR_FAILURE);
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(ifreq));
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIWebBrowserFind> webBrowserFind(do_GetInterface(docShell));
NS_ENSURE_TRUE(webBrowserFind, NS_ERROR_FAILURE);
NS_ADDREF(*aWebBrowserFind = webBrowserFind);
return NS_OK;
}
void
nsTypeAheadFind::StartTimeout()
{
if (mTimeoutLength) {
if (!mTimer) {
mTimer = do_CreateInstance("@mozilla.org/timer;1");
}
if (mTimer) {
mTimer->InitWithCallback(this, mTimeoutLength, nsITimer::TYPE_ONE_SHOT);
}
}
}
void
nsTypeAheadFind::SetSelectionLook(nsIPresShell *aPresShell,
PRBool aChangeColor,
@ -1674,7 +1787,7 @@ nsTypeAheadFind::RemoveWindowListeners(nsIDOMWindow *aDOMWin)
// Use capturing, otherwise the normal find next will get activated when ours should
chromeEventHandler->RemoveEventListener(NS_LITERAL_STRING("keypress"),
NS_STATIC_CAST(nsIDOMKeyListener*, this),
PR_TRUE);
PR_FALSE);
}
if (aDOMWin == mFocusedWindow) {
@ -1705,11 +1818,13 @@ nsTypeAheadFind::AttachWindowListeners(nsIDOMWindow *aDOMWin)
{
nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
GetChromeEventHandler(aDOMWin, getter_AddRefs(chromeEventHandler));
if (chromeEventHandler)
if (chromeEventHandler) {
// Use capturing, otherwise the normal find next will get activated when ours should
chromeEventHandler->AddEventListener(NS_LITERAL_STRING("keypress"),
NS_STATIC_CAST(nsIDOMKeyListener*, this),
PR_TRUE);
PR_FALSE);
}
// Attach menu listeners, this will help us ignore keystrokes meant for menus
chromeEventHandler->AddEventListener(NS_LITERAL_STRING("popupshown"),
NS_STATIC_CAST(nsIDOMEventListener*, this),

View File

@ -48,6 +48,7 @@
#include "nsUnicharUtils.h"
#include "nsIFindService.h"
#include "nsIFind.h"
#include "nsIWebBrowserFind.h"
#include "nsWeakReference.h"
#include "nsIAppStartupNotifier.h"
#include "nsIPresShell.h"
@ -112,6 +113,8 @@ protected:
static int PR_CALLBACK PrefsReset(const char* aPrefName, void* instance);
// Helper methods
nsresult GetWebBrowserFind(nsIWebBrowserFind **aWebBrowserFind);
void StartTimeout();
nsresult Init();
nsresult UseInWindow(nsIDOMWindow *aDomWin);
void SetSelectionLook(nsIPresShell *aPresShell, PRBool aChangeColor,

View File

@ -2857,6 +2857,7 @@ nsBoxFrame::RegUnregAccessKey(nsIPresContext* aPresContext,
// only support accesskeys for the following elements
if (atom != nsXULAtoms::button &&
atom != nsXULAtoms::checkbox &&
atom != nsXULAtoms::textbox &&
atom != nsXULAtoms::radio) {
return NS_OK;

View File

@ -260,6 +260,7 @@ var DefaultController =
case "cmd_getNextNMessages":
case "cmd_find":
case "cmd_findAgain":
case "cmd_findPrev":
case "cmd_search":
case "button_mark":
case "cmd_markAsRead":
@ -393,6 +394,7 @@ var DefaultController =
return (MailAreaHasFocus() && IsFolderSelected());
case "cmd_find":
case "cmd_findAgain":
case "cmd_findPrev":
return IsMessageDisplayedInMessagePane();
break;
case "cmd_search":
@ -598,7 +600,10 @@ var DefaultController =
MsgFind();
return;
case "cmd_findAgain":
MsgFindAgain();
MsgFindAgain(false);
return;
case "cmd_findPrev":
MsgFindAgain(true);
return;
case "cmd_properties":
MsgFolderProperties();

View File

@ -1191,10 +1191,10 @@ function MsgFind()
findInPage(getMessageBrowser(), contentWindow, contentWindow)
}
function MsgFindAgain()
function MsgFindAgain(reverse)
{
var contentWindow = window.top._content;
findAgainInPage(getMessageBrowser(), contentWindow, contentWindow)
findAgainInPage(getMessageBrowser(), contentWindow, contentWindow, reverse)
}
function MsgCanFindAgain()

View File

@ -172,6 +172,7 @@ Rights Reserved.
valueGeneric="&folderPropsCmd.label;"/>
<command id="cmd_find" oncommand="goDoCommand('cmd_find')" disabled="true"/>
<command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')" disabled="true"/>
<command id="cmd_findPrev" oncommand="goDoCommand('cmd_findPrev')" disabled="true"/>
<command id="cmd_stop" oncommand="MsgStop();"/>
</commandset>
@ -316,6 +317,9 @@ Rights Reserved.
modifiers="accel, shift"/>
<key id="key_find" key="&findCmd.key;" oncommand="goDoCommand('cmd_find')" modifiers="accel"/>
<key id="key_findAgain" key="&findAgainCmd.key;" oncommand="goDoCommand('cmd_findAgain')" modifiers="accel"/>
<key id="key_findPrev" key="&findPrevCmd.key;" oncommand="goDoCommand('cmd_findPrev')" modifiers="accel, shift"/>
<key keycode="&findAgainCmd.key2;" oncommand="goDoCommand('cmd_findAgain')"/>
<key keycode="&findPrevCmd.key2;" oncommand="goDoCommand('cmd_findPrev')" modifiers="shift"/>
<key id="key_stop" keycode="VK_ESCAPE" command="cmd_stop"/>
<keyset id="viewZoomKeys"/>
@ -1026,6 +1030,7 @@ Rights Reserved.
<menuseparator/>
<menuitem label="&findCmd.label;" key="key_find" accesskey="&findCmd.accesskey;" observes="cmd_find"/>
<menuitem label="&findAgainCmd.label;" key="key_findAgain" accesskey="&findAgainCmd.accesskey;" observes="cmd_findAgain"/>
<menuitem label="&findPrevCmd.label;" key="key_findPrev" accesskey="&findPrevCmd.accesskey;" observes="cmd_findPrev"/>
<menuseparator/>
<menuitem id="menu_properties" label="&folderPropsCmd.label;"
accesskey="&folderPropsCmd.accesskey;"

View File

@ -572,6 +572,7 @@ var MessageWindowController =
case "cmd_getNextNMessages":
case "cmd_find":
case "cmd_findAgain":
case "cmd_findPrev":
case "cmd_search":
case "button_mark":
case "cmd_markAsRead":
@ -679,6 +680,7 @@ var MessageWindowController =
case "cmd_previousUnreadMsg":
return true;
case "cmd_findAgain":
case "cmd_findPrev":
return MsgCanFindAgain();
case "cmd_search":
var loadedFolder = GetLoadedMsgFolder();
@ -784,7 +786,10 @@ var MessageWindowController =
MsgFind();
break;
case "cmd_findAgain":
MsgFindAgain();
MsgFindAgain(false);
break;
case "cmd_findPrev":
MsgFindAgain(true);
break;
case "cmd_search":
MsgSearchMessages();

View File

@ -232,6 +232,11 @@ Rights Reserved.
<!ENTITY findAgainCmd.label "Find Again">
<!ENTITY findAgainCmd.accesskey "g">
<!ENTITY findAgainCmd.key "g">
<!ENTITY findAgainCmd.key2 "VK_F3">
<!ENTITY findPrevCmd.label "Find Previous">
<!ENTITY findPrevCmd.accesskey "v">
<!ENTITY findPrevCmd.key "g">
<!ENTITY findPrevCmd.key2 "VK_F3">
<!-- LOCALIZATION NOTE (searchCurrentCmd.label) : Do not translate "&lt;" and "&gt;" in below line. -->
<!ENTITY searchCurrentCmd.label ".Search in &lt;current&gt;">
<!ENTITY searchCurrentCmd.accesskey "">

View File

@ -163,6 +163,9 @@
<key id="key_selectAll"/>
<key id="key_find" key="&findCmd.key;" command="cmd_find" modifiers="accel"/>
<key id="key_findNext" key="&findAgainCmd.key;" command="cmd_findNext" modifiers="accel"/>
<key id="key_findPrev" key="&findPrevCmd.key;" command="cmd_findPrev" modifiers="accel, shift"/>
<key keycode="&findAgainCmd.key2;" command="cmd_findNext"/>
<key keycode="&findPrevCmd.key2;" command="cmd_findPrev" modifiers="shift"/>
<!-- Options Menu -->
<!-- key id="key_selectAddresses" xulkey="true" key="&selectAddressCmd.key;" command="cmd_selectAddress"/ -->
@ -246,6 +249,7 @@
<menuseparator/>
<menuitem label="&findCmd.label;" key="key_find" accesskey="&findCmd.accesskey;" command="cmd_find"/>
<menuitem label="&findAgainCmd.label;" key="key_findNext" accesskey="&findAgainCmd.accesskey;" command="cmd_findNext"/>
<menuitem label="&findPrevCmd.label;" key="key_findPrev" accesskey="&findPrevCmd.accesskey;" command="cmd_findPrev"/>
<menuseparator/>
<menuitem label="&accountManagerCmd.label;" accesskey="&accountManagerCmd.accesskey;" command="cmd_account"/>
<menuitem id="menu_preferences" oncommand="goDoCommand('cmd_preferences')"/>

View File

@ -49,6 +49,11 @@
<!ENTITY findAgainCmd.label "Find Again">
<!ENTITY findAgainCmd.key "G">
<!ENTITY findAgainCmd.accesskey "g">
<!ENTITY findAgainCmd.key2 "VK_F3">
<!ENTITY findPrevCmd.label "Find Previous">
<!ENTITY findPrevCmd.key "G">
<!ENTITY findPrevCmd.key2 "VK_F3">
<!ENTITY findPrevCmd.accesskey "v">
<!ENTITY accountManagerCmd.label "Mail &amp; Newsgroups Account Settings...">
<!ENTITY accountManagerCmd.accesskey "m">

View File

@ -382,13 +382,13 @@ function BrowserFind()
findInPage(getBrowser(), window._content, focusedWindow)
}
function BrowserFindAgain()
function BrowserFindAgain(reverse)
{
var focusedWindow = document.commandDispatcher.focusedWindow;
if (!focusedWindow || focusedWindow == window)
focusedWindow = window._content;
findAgainInPage(getBrowser(), window._content, focusedWindow)
findAgainInPage(getBrowser(), window._content, focusedWindow, reverse)
}
function BrowserCanFindAgain()

View File

@ -161,7 +161,7 @@ Contributor(s):
<textbox id="urlbar" class="chromeclass-location" flex="1"
type="autocomplete" searchSessions="history"
timeout="50" maxrows="6" alwaysopenpopup="true"
disablehistory="false"
disablehistory="false" accesskey="d"
defaultSearchEngine="true" tabScrolling="true"
showCommentColumn="true"
inputtooltiptext="&locationBar.tooltip;"

View File

@ -80,8 +80,11 @@
<key id="key_viewPrevSidebarPanel" keycode="VK_PAGE_UP" oncommand="SidebarGetRelativePanel(-1);" modifiers="alt" />
<!-- Search Menu -->
<key id="key_find" key="&findOnCmd.commandkey;" command="Browser:Find" modifiers="accel"/>
<key id="key_findAgain" key="&findAgainCmd.commandkey;" command="Browser:FindAgain" modifiers="accel"/>
<key id="key_find" key="&findOnCmd.commandkey;" command="Browser:Find" modifiers="accel"/>
<key id="key_findAgain" key="&findAgainCmd.commandkey;" command="Browser:FindAgain" modifiers="accel"/>
<key id="key_findPrev" key="&findPrevCmd.commandkey;" command="Browser:FindPrev" modifiers="accel,shift"/>
<key keycode="&findAgainCmd.commandkey2;" command="Browser:FindAgain"/>
<key keycode="&findPrevCmd.commandkey2;" command="Browser:FindPrev" modifiers="shift"/>
<!-- Go Menu -->
@ -143,7 +146,8 @@
<!-- Search Menu -->
<command id="Browser:Find" oncommand="BrowserFind();" observes="isImage"/>
<command id="Browser:FindAgain" oncommand="BrowserFindAgain();" observes="isImage"/>
<command id="Browser:FindAgain" oncommand="BrowserFindAgain(false);" observes="isImage"/>
<command id="Browser:FindPrev" oncommand="BrowserFindAgain(true);" observes="isImage"/>
<!-- Bookmarks Menu -->
<command id="Browser:AddBookmark" label="&addCurPageCmd.label;" accesskey="&addCurPageCmd.accesskey;"
@ -226,6 +230,7 @@
<menuseparator/>
<menuitem id="menu_find" label="&findOnCmd.label;" accesskey="&findOnCmd.accesskey;" key="key_find" command="Browser:Find"/>
<menuitem id="menu_findAgain" label="&findAgainCmd.label;" accesskey="&findAgainCmd.accesskey;" key="key_findAgain" command="Browser:FindAgain"/>
<menuitem id="menu_findPrev" label="&findPrevCmd.label;" accesskey="&findPrevCmd.accesskey;" key="key_findPrev" command="Browser:FindPrev"/>
<menuseparator id="menu_PrefsSeparator"/>
<menuitem id="menu_preferences" oncommand="goPreferences('navigator', 'chrome://communicator/content/pref/pref-navigator.xul', 'navigator')"/>
</menupopup>
@ -362,7 +367,7 @@
<menu accesskey="&helpMenuCmd.accesskey;" id="menu_Help"/>
<!-- Menu for testing. -->
<menu id="debugMenu" accesskey="D" label="Debug">
<menu id="debugMenu" accesskey="U" label="Debug">
<menupopup>
<menu label="Verification">
<menupopup>

View File

@ -98,6 +98,9 @@
<key id="key_selectAll"/>
<key id="key_find" key="&findOnCmd.commandkey;" command="Browser:Find" modifiers="accel"/>
<key id="key_findAgain" key="&findAgainCmd.commandkey;" command="Browser:FindAgain" modifiers="accel"/>
<key id="key_findNext" key="&findPrevCmd.commandkey;" command="Browser:FindPrev" modifiers="accel, shift"/>
<key keycode="&findAgainCmd.commandkey2;" command="Browser:FindAgain"/>
<key keycode="&findPrevCmd.commandkey2;" command="Browser:FindPrev" modifiers="shift"/>
<keyset id="viewZoomKeys"/>
</keyset>
@ -157,6 +160,8 @@
label="&findOnCmd.label;" accesskey="&findOnCmd.accesskey;"/>
<menuitem id="menu_findAgain" key="key_findAgain" command="Browser:FindAgain"
label="&findAgainCmd.label;" accesskey="&findAgainCmd.accesskey;"/>
<menuitem id="menu_findPrev" key="key_findPrev" command="Browser:FindPrev"
label="&findPrevCmd.label;" accesskey="&findPrevCmd.accesskey;"/>
</menupopup>
</menu>

View File

@ -9,11 +9,6 @@
<key id="goBackKb" keycode="VK_LEFT" command="Browser:Back" modifiers="alt"/>
<key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="alt"/>
<!-- Supporting IE forward and back accelerators out of courtesy
to transitioning IE users -->
<key keycode="VK_BACK" command="Browser:Back"/>
<key keycode="VK_BACK" command="Browser:Forward" modifiers="shift"/>
<!-- Supporting IE 'refresh' shortcut key -->
<key keycode="VK_F5" oncommand="BrowserReload();"/>
<key keycode="VK_F5" modifiers="control" oncommand="BrowserReloadSkipCache();"/>

View File

@ -116,6 +116,11 @@
<!ENTITY findAgainCmd.label "Find Again">
<!ENTITY findAgainCmd.accesskey "g">
<!ENTITY findAgainCmd.commandkey "g">
<!ENTITY findPrevCmd.label "Find Previous">
<!ENTITY findPrevCmd.accesskey "v">
<!ENTITY findPrevCmd.commandkey "g">
<!ENTITY findAgainCmd.commandkey2 "VK_F3">
<!ENTITY findPrevCmd.commandkey2 "VK_F3">
<!ENTITY searchInternetCmd.label "Search the Web">
<!ENTITY searchInternetCmd.accesskey "S">

View File

@ -61,7 +61,7 @@ function findInPage(browser, rootSearchWindow, startSearchWindow)
window.findDialog = window.openDialog("chrome://global/content/finddialog.xul", "_blank", "chrome,resizable=no,dependent=yes", findInst);
}
function findAgainInPage(browser, rootSearchWindow, startSearchWindow)
function findAgainInPage(browser, rootSearchWindow, startSearchWindow, reverse)
{
if ("findDialog" in window && window.findDialog)
window.findDialog.focus();
@ -85,7 +85,7 @@ function findAgainInPage(browser, rootSearchWindow, startSearchWindow)
findInst.matchCase = findService.matchCase;
findInst.wrapFind = findService.wrapFind;
findInst.entireWord = findService.entireWord;
findInst.findBackwards = findService.findBackwards;
findInst.findBackwards = findService.findBackwards ^ reverse;
var found = false;
if (findInst.searchString.length == 0) {
@ -104,6 +104,9 @@ function findAgainInPage(browser, rootSearchWindow, startSearchWindow)
gPromptService.alert(window, gFindBundle.getString("notFoundTitle"), gFindBundle.getString("notFoundWarning"));
}
// Reset to normal value, otherwise setting can get changed in find dialog
findInst.findBackwards = findService.findBackwards;
}
}