зеркало из https://github.com/mozilla/gecko-dev.git
Bug 493251 - Header/navigation links on PG.com take two clicks to load, r+sr=jst
This commit is contained in:
Родитель
64240859c8
Коммит
a3215e3235
|
@ -69,6 +69,7 @@ _TEST_FILES = \
|
|||
bug457672.html \
|
||||
test_draggableprop.html \
|
||||
test_dragstart.html \
|
||||
test_bug493251.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=493251
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 493251</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=493251">Mozilla Bug 493251</a>
|
||||
<p id="display">
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 493251 **/
|
||||
|
||||
var win;
|
||||
|
||||
var mouseDown = 0;
|
||||
var mouseUp = 0;
|
||||
var mouseClick = 0;
|
||||
|
||||
var keyDown = 0;
|
||||
var keyPress = 0;
|
||||
var keyUp = 0;
|
||||
|
||||
function dispatchKeyEvent(type) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
utils.sendKeyEvent(type,
|
||||
Components.interfaces.nsIDOMKeyEvent.DOM_VK_A,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
win.document.getElementsByTagName("input")[0].focus();
|
||||
win.addEventListener("keydown", function(e) { ++keyDown; }, true);
|
||||
win.addEventListener("keypress", function(e) { ++keyPress; }, true);
|
||||
win.addEventListener("keyup", function(e) { ++keyUp; }, true);
|
||||
win.addEventListener("mousedown", function(e) { ++mouseDown; }, true);
|
||||
win.addEventListener("mouseup", function(e) { ++mouseUp; }, true);
|
||||
win.addEventListener("click", function(e) { ++mouseClick; }, true);
|
||||
|
||||
dispatchKeyEvent("keydown");
|
||||
dispatchKeyEvent("keypress");
|
||||
dispatchKeyEvent("keyup");
|
||||
is(keyDown, 1, "Wrong number events (1)");
|
||||
is(keyPress, 1, "Wrong number events (2)");
|
||||
is(keyUp, 1, "Wrong number events (3)");
|
||||
|
||||
utils.suppressEventHandling(true);
|
||||
dispatchKeyEvent("keydown");
|
||||
dispatchKeyEvent("keypress");
|
||||
dispatchKeyEvent("keyup");
|
||||
is(keyDown, 1, "Wrong number events (4)");
|
||||
is(keyPress, 1, "Wrong number events (5)");
|
||||
is(keyUp, 1, "Wrong number events (6)");
|
||||
utils.suppressEventHandling(false);
|
||||
is(keyDown, 1, "Wrong number events (7)");
|
||||
is(keyPress, 1, "Wrong number events (8)");
|
||||
is(keyUp, 1, "Wrong number events (9)");
|
||||
|
||||
setTimeout(continueTest1, 0);
|
||||
}
|
||||
|
||||
function continueTest1() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
dispatchKeyEvent("keydown");
|
||||
utils.suppressEventHandling(true);
|
||||
dispatchKeyEvent("keypress");
|
||||
dispatchKeyEvent("keyup");
|
||||
is(keyDown, 2, "Wrong number events (10)");
|
||||
is(keyPress, 1, "Wrong number events (11)");
|
||||
is(keyUp, 1, "Wrong number events (12)");
|
||||
utils.suppressEventHandling(false);
|
||||
setTimeout(continueTest2, 0);
|
||||
}
|
||||
|
||||
function continueTest2() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
is(keyDown, 2, "Wrong number events (13)");
|
||||
is(keyPress, 2, "Wrong number events (14)");
|
||||
is(keyUp, 2, "Wrong number events (15)");
|
||||
|
||||
utils.sendMouseEvent("mousedown", 5, 5, 0, 1, 0);
|
||||
utils.sendMouseEvent("mouseup", 5, 5, 0, 1, 0);
|
||||
is(mouseDown, 1, "Wrong number events (16)");
|
||||
is(mouseUp, 1, "Wrong number events (17)");
|
||||
is(mouseClick, 1, "Wrong number events (18)");
|
||||
|
||||
utils.suppressEventHandling(true);
|
||||
utils.sendMouseEvent("mousedown", 5, 5, 0, 1, 0);
|
||||
utils.sendMouseEvent("mouseup", 5, 5, 0, 1, 0);
|
||||
utils.suppressEventHandling(false);
|
||||
is(mouseDown, 1, "Wrong number events (19)");
|
||||
is(mouseUp, 1, "Wrong number events (20)");
|
||||
is(mouseClick, 1, "Wrong number events (21)");
|
||||
|
||||
setTimeout(continueTest3, 0);
|
||||
}
|
||||
|
||||
function continueTest3() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
utils.sendMouseEvent("mousedown", 5, 5, 0, 1, 0);
|
||||
utils.suppressEventHandling(true);
|
||||
utils.sendMouseEvent("mouseup", 5, 5, 0, 1, 0);
|
||||
utils.suppressEventHandling(false);
|
||||
setTimeout(continueTest4, 1000);
|
||||
}
|
||||
|
||||
function continueTest4() {
|
||||
is(mouseDown, 2, "Wrong number events (19)");
|
||||
is(mouseUp, 2, "Wrong number events (20)");
|
||||
is(mouseClick, 2, "Wrong number events (21)");
|
||||
win.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
win = window.open("data:text/html,<input>", "" , "");
|
||||
win.onload = doTest;
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1180,18 +1180,118 @@ protected:
|
|||
PRIntn mContentScrollVPosition;
|
||||
PRIntn mContentScrollHPosition;
|
||||
|
||||
struct nsBlurOrFocusTarget
|
||||
class nsDelayedEvent
|
||||
{
|
||||
nsBlurOrFocusTarget(nsPIDOMEventTarget* aTarget, PRUint32 aEventType)
|
||||
public:
|
||||
virtual ~nsDelayedEvent() {};
|
||||
virtual void Dispatch(PresShell* aShell) {}
|
||||
// This is needed only by nsDelayedFocusBlur.
|
||||
virtual PRBool Equals(nsPIDOMEventTarget* aTarget, PRUint32 aEventType)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
};
|
||||
|
||||
class nsDelayedFocusBlur : public nsDelayedEvent
|
||||
{
|
||||
public:
|
||||
nsDelayedFocusBlur(nsPIDOMEventTarget* aTarget, PRUint32 aEventType)
|
||||
: mTarget(aTarget), mEventType(aEventType) {}
|
||||
nsBlurOrFocusTarget(const nsBlurOrFocusTarget& aOther)
|
||||
: mTarget(aOther.mTarget), mEventType(aOther.mEventType) {}
|
||||
|
||||
virtual void Dispatch(PresShell* aShell)
|
||||
{
|
||||
nsEvent event(PR_TRUE, mEventType);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
nsEventDispatcher::Dispatch(mTarget, aShell->GetPresContext(), &event);
|
||||
}
|
||||
|
||||
virtual PRBool Equals(nsPIDOMEventTarget* aTarget, PRUint32 aEventType)
|
||||
{
|
||||
return aTarget == mTarget && aEventType == mEventType;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMEventTarget> mTarget;
|
||||
PRUint32 mEventType;
|
||||
};
|
||||
|
||||
nsTArray<nsBlurOrFocusTarget> mDelayedBlurFocusTargets;
|
||||
class nsDelayedInputEvent : public nsDelayedEvent
|
||||
{
|
||||
public:
|
||||
virtual void Dispatch(PresShell* aShell)
|
||||
{
|
||||
if (mEvent && mEvent->widget) {
|
||||
nsCOMPtr<nsIWidget> w = mEvent->widget;
|
||||
nsEventStatus status;
|
||||
w->DispatchEvent(mEvent, status);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init(nsInputEvent* aEvent)
|
||||
{
|
||||
mEvent->time = aEvent->time;
|
||||
mEvent->refPoint = aEvent->refPoint;
|
||||
mEvent->isShift = aEvent->isShift;
|
||||
mEvent->isControl = aEvent->isControl;
|
||||
mEvent->isAlt = aEvent->isAlt;
|
||||
mEvent->isMeta = aEvent->isMeta;
|
||||
}
|
||||
|
||||
nsDelayedInputEvent()
|
||||
: nsDelayedEvent(), mEvent(nsnull) {}
|
||||
|
||||
nsInputEvent* mEvent;
|
||||
};
|
||||
|
||||
class nsDelayedMouseEvent : public nsDelayedInputEvent
|
||||
{
|
||||
public:
|
||||
nsDelayedMouseEvent(nsMouseEvent* aEvent) : nsDelayedInputEvent()
|
||||
{
|
||||
mEvent = new nsMouseEvent(NS_IS_TRUSTED_EVENT(aEvent),
|
||||
aEvent->message,
|
||||
aEvent->widget,
|
||||
aEvent->reason,
|
||||
aEvent->context);
|
||||
if (mEvent) {
|
||||
Init(aEvent);
|
||||
static_cast<nsMouseEvent*>(mEvent)->clickCount = aEvent->clickCount;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~nsDelayedMouseEvent()
|
||||
{
|
||||
delete static_cast<nsMouseEvent*>(mEvent);
|
||||
}
|
||||
};
|
||||
|
||||
class nsDelayedKeyEvent : public nsDelayedInputEvent
|
||||
{
|
||||
public:
|
||||
nsDelayedKeyEvent(nsKeyEvent* aEvent) : nsDelayedInputEvent()
|
||||
{
|
||||
mEvent = new nsKeyEvent(NS_IS_TRUSTED_EVENT(aEvent),
|
||||
aEvent->message,
|
||||
aEvent->widget);
|
||||
if (mEvent) {
|
||||
Init(aEvent);
|
||||
static_cast<nsKeyEvent*>(mEvent)->keyCode = aEvent->keyCode;
|
||||
static_cast<nsKeyEvent*>(mEvent)->charCode = aEvent->charCode;
|
||||
static_cast<nsKeyEvent*>(mEvent)->alternativeCharCodes =
|
||||
aEvent->alternativeCharCodes;
|
||||
static_cast<nsKeyEvent*>(mEvent)->isChar = aEvent->isChar;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~nsDelayedKeyEvent()
|
||||
{
|
||||
delete static_cast<nsKeyEvent*>(mEvent);
|
||||
}
|
||||
};
|
||||
|
||||
PRPackedBool mNoDelayedMouseEvents;
|
||||
PRPackedBool mNoDelayedKeyEvents;
|
||||
nsTArray<nsAutoPtr<nsDelayedEvent> > mDelayedEvents;
|
||||
|
||||
nsCallbackEventRequest* mFirstCallbackEventRequest;
|
||||
nsCallbackEventRequest* mLastCallbackEventRequest;
|
||||
|
@ -5880,10 +5980,27 @@ PresShell::HandleEvent(nsIView *aView,
|
|||
aEvent->message == NS_DEACTIVATE);
|
||||
if (mDocument && mDocument->EventHandlingSuppressed()) {
|
||||
if (!widgetHandlingEvent) {
|
||||
nsDelayedEvent* event = nsnull;
|
||||
if (aEvent->eventStructType == NS_KEY_EVENT) {
|
||||
if (aEvent->message == NS_KEY_DOWN) {
|
||||
mNoDelayedKeyEvents = PR_TRUE;
|
||||
} else if (!mNoDelayedKeyEvents) {
|
||||
event = new nsDelayedKeyEvent(static_cast<nsKeyEvent*>(aEvent));
|
||||
}
|
||||
} else if (aEvent->eventStructType == NS_MOUSE_EVENT) {
|
||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
||||
mNoDelayedMouseEvents = PR_TRUE;
|
||||
} else if (!mNoDelayedMouseEvents && aEvent->message == NS_MOUSE_BUTTON_UP) {
|
||||
event = new nsDelayedMouseEvent(static_cast<nsMouseEvent*>(aEvent));
|
||||
}
|
||||
}
|
||||
if (event && !mDelayedEvents.AppendElement(event)) {
|
||||
delete event;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
} else if (widgetHandlingEvent) {
|
||||
mDelayedBlurFocusTargets.Clear();
|
||||
FireOrClearDelayedEvents(PR_FALSE);
|
||||
}
|
||||
|
||||
nsIFrame* frame = static_cast<nsIFrame*>(aView->GetClientData());
|
||||
|
@ -6731,22 +6848,21 @@ PresShell::Freeze()
|
|||
void
|
||||
PresShell::FireOrClearDelayedEvents(PRBool aFireEvents)
|
||||
{
|
||||
mNoDelayedMouseEvents = PR_FALSE;
|
||||
mNoDelayedKeyEvents = PR_FALSE;
|
||||
if (!aFireEvents) {
|
||||
mDelayedBlurFocusTargets.Clear();
|
||||
mDelayedEvents.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mIsDestroying && mDocument) {
|
||||
nsCOMPtr<nsIDocument> doc = mDocument;
|
||||
while (mDelayedBlurFocusTargets.Length() && !doc->EventHandlingSuppressed()) {
|
||||
nsEvent event(PR_TRUE, mDelayedBlurFocusTargets[0].mEventType);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
nsEventDispatcher::Dispatch(mDelayedBlurFocusTargets[0].mTarget,
|
||||
mPresContext, &event);
|
||||
mDelayedBlurFocusTargets.RemoveElementAt(0);
|
||||
while (mDelayedEvents.Length() && !doc->EventHandlingSuppressed()) {
|
||||
mDelayedEvents[0]->Dispatch(this);
|
||||
mDelayedEvents.RemoveElementAt(0);
|
||||
}
|
||||
if (!doc->EventHandlingSuppressed()) {
|
||||
mDelayedBlurFocusTargets.Clear();
|
||||
mDelayedEvents.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6756,14 +6872,16 @@ PresShell::NeedsFocusOrBlurAfterSuppression(nsPIDOMEventTarget* aTarget,
|
|||
PRUint32 aEventType)
|
||||
{
|
||||
if (mDocument && mDocument->EventHandlingSuppressed()) {
|
||||
for (PRUint32 i = mDelayedBlurFocusTargets.Length(); i > 0; --i) {
|
||||
if (mDelayedBlurFocusTargets[i - 1].mTarget == aTarget &&
|
||||
mDelayedBlurFocusTargets[i - 1].mEventType == aEventType) {
|
||||
mDelayedBlurFocusTargets.RemoveElementAt(i - 1);
|
||||
for (PRUint32 i = mDelayedEvents.Length(); i > 0; --i) {
|
||||
if (mDelayedEvents[i - 1]->Equals(aTarget, aEventType)) {
|
||||
mDelayedEvents.RemoveElementAt(i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
mDelayedBlurFocusTargets.AppendElement(nsBlurOrFocusTarget(aTarget, aEventType));
|
||||
nsDelayedFocusBlur* delayed = new nsDelayedFocusBlur(aTarget, aEventType);
|
||||
if (delayed && !mDelayedEvents.AppendElement(delayed)) {
|
||||
delete delayed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче