зеркало из https://github.com/mozilla/pjs.git
Bug 591890 focus() method should be able to steal focus when it's called from mousedown event handler r=enndeakin, a=betaN+
This commit is contained in:
Родитель
4f4e3e1958
Коммит
cbf3c63357
|
@ -54,6 +54,8 @@
|
|||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIMarkupDocumentViewer.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
class nsIPresShell;
|
||||
class nsIDocShell;
|
||||
|
@ -436,14 +438,25 @@ protected:
|
|||
class nsAutoHandlingUserInputStatePusher
|
||||
{
|
||||
public:
|
||||
nsAutoHandlingUserInputStatePusher(PRBool aIsHandlingUserInput, PRBool aIsMouseDown)
|
||||
: mIsHandlingUserInput(aIsHandlingUserInput), mIsMouseDown(aIsMouseDown)
|
||||
nsAutoHandlingUserInputStatePusher(PRBool aIsHandlingUserInput,
|
||||
nsEvent* aEvent,
|
||||
nsIDocument* aDocument)
|
||||
: mIsHandlingUserInput(aIsHandlingUserInput),
|
||||
mIsMouseDown(aEvent && aEvent->message == NS_MOUSE_BUTTON_DOWN),
|
||||
mResetFMMouseDownState(PR_FALSE)
|
||||
{
|
||||
if (aIsHandlingUserInput) {
|
||||
nsEventStateManager::StartHandlingUserInput();
|
||||
if (aIsMouseDown) {
|
||||
if (mIsMouseDown) {
|
||||
nsIPresShell::SetCapturingContent(nsnull, 0);
|
||||
nsIPresShell::AllowMouseCapture(PR_TRUE);
|
||||
if (aDocument && NS_IS_TRUSTED_EVENT(aEvent)) {
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
fm->SetMouseButtonDownHandlingDocument(aDocument);
|
||||
mResetFMMouseDownState = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -454,6 +467,12 @@ public:
|
|||
nsEventStateManager::StopHandlingUserInput();
|
||||
if (mIsMouseDown) {
|
||||
nsIPresShell::AllowMouseCapture(PR_FALSE);
|
||||
if (mResetFMMouseDownState) {
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
fm->SetMouseButtonDownHandlingDocument(nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -461,6 +480,7 @@ public:
|
|||
protected:
|
||||
PRBool mIsHandlingUserInput;
|
||||
PRBool mIsMouseDown;
|
||||
PRBool mResetFMMouseDownState;
|
||||
|
||||
private:
|
||||
// Hide so that this class can only be stack-allocated
|
||||
|
|
|
@ -881,7 +881,9 @@ nsHTMLFormElement::SubmitSubmission(nsFormSubmission* aFormSubmission)
|
|||
{
|
||||
nsAutoPopupStatePusher popupStatePusher(mSubmitPopupState);
|
||||
|
||||
nsAutoHandlingUserInputStatePusher userInpStatePusher(mSubmitInitiatedFromUserInput, PR_FALSE);
|
||||
nsAutoHandlingUserInputStatePusher userInpStatePusher(
|
||||
mSubmitInitiatedFromUserInput,
|
||||
nsnull, doc);
|
||||
|
||||
nsCOMPtr<nsIInputStream> postDataStream;
|
||||
rv = aFormSubmission->GetEncodedSubmission(actionURI,
|
||||
|
|
|
@ -1126,6 +1126,12 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, PRInt32 aFlags,
|
|||
// is in chrome, any web contents should not be able to steal the focus.
|
||||
nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mFocusedContent));
|
||||
sendFocusEvent = nsContentUtils::CanCallerAccess(domNode);
|
||||
if (!sendFocusEvent && mMouseDownEventHandlingDocument) {
|
||||
// However, while mouse down event is handling, the handling document's
|
||||
// script should be able to steal focus.
|
||||
domNode = do_QueryInterface(mMouseDownEventHandlingDocument);
|
||||
sendFocusEvent = nsContentUtils::CanCallerAccess(domNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (sendFocusEvent) {
|
||||
|
|
|
@ -88,6 +88,16 @@ public:
|
|||
*/
|
||||
nsresult ContentRemoved(nsIDocument* aDocument, nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Called when mouse button down event handling is started and finished.
|
||||
*/
|
||||
void SetMouseButtonDownHandlingDocument(nsIDocument* aDocument)
|
||||
{
|
||||
NS_ASSERTION(!aDocument || !mMouseDownEventHandlingDocument,
|
||||
"Some mouse button down events are nested?");
|
||||
mMouseDownEventHandlingDocument = aDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content node that would be focused if aWindow was in an
|
||||
* active window. This will traverse down the frame hierarchy, starting at
|
||||
|
@ -467,6 +477,14 @@ protected:
|
|||
// and fire them later.
|
||||
nsTArray<nsDelayedBlurOrFocusEvent> mDelayedBlurFocusEvents;
|
||||
|
||||
// A document which is handling a mouse button down event.
|
||||
// When a mouse down event process is finished, ESM sets focus to the target
|
||||
// content. Therefore, while DOM event handlers are handling mouse down
|
||||
// events, the handlers should be able to steal focus from any elements even
|
||||
// if focus is in chrome content. So, if this isn't NULL and the caller
|
||||
// can access the document node, the caller should succeed in moving focus.
|
||||
nsCOMPtr<nsIDocument> mMouseDownEventHandlingDocument;
|
||||
|
||||
// the single focus manager
|
||||
static nsFocusManager* sInstance;
|
||||
};
|
||||
|
|
|
@ -46,6 +46,7 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
_BROWSER_FILES = \
|
||||
browser_focus_steal_from_chrome.js \
|
||||
browser_focus_steal_from_chrome_during_mousedown.js \
|
||||
browser_autofocus_background.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -6901,7 +6901,7 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
|
|||
}
|
||||
|
||||
nsAutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput,
|
||||
aEvent->message == NS_MOUSE_BUTTON_DOWN);
|
||||
aEvent, mDocument);
|
||||
|
||||
if (NS_IS_TRUSTED_EVENT(aEvent) && aEvent->message == NS_MOUSE_MOVE) {
|
||||
nsIPresShell::AllowMouseCapture(
|
||||
|
|
|
@ -2264,7 +2264,8 @@ nsXULMenuCommandEvent::Run()
|
|||
if (mCloseMenuMode != CloseMenuMode_None)
|
||||
menuFrame->SelectMenu(PR_FALSE);
|
||||
|
||||
nsAutoHandlingUserInputStatePusher userInpStatePusher(mUserInput, PR_FALSE);
|
||||
nsAutoHandlingUserInputStatePusher userInpStatePusher(mUserInput, nsnull,
|
||||
shell->GetDocument());
|
||||
nsContentUtils::DispatchXULCommand(mMenu, mIsTrusted, nsnull, shell,
|
||||
mControl, mAlt, mShift, mMeta);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче