1998-06-23 21:53:02 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The contents of this file are subject to the Netscape Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/NPL/
|
1998-06-23 21:53:02 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
1998-06-23 21:53:02 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1998-06-23 21:53:02 +00:00
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-11-06 03:40:37 +00:00
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
1998-06-23 21:53:02 +00:00
|
|
|
*/
|
1999-02-12 17:45:58 +00:00
|
|
|
#include "nsCOMPtr.h"
|
1998-06-23 21:53:02 +00:00
|
|
|
#include "nsIEventStateManager.h"
|
|
|
|
#include "nsEventStateManager.h"
|
1998-08-07 04:45:03 +00:00
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsIDocument.h"
|
1998-11-18 05:25:26 +00:00
|
|
|
#include "nsIFrame.h"
|
|
|
|
#include "nsIWidget.h"
|
|
|
|
#include "nsIStyleContext.h"
|
|
|
|
#include "nsIPresContext.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsDOMEvent.h"
|
|
|
|
#include "nsHTMLAtoms.h"
|
|
|
|
#include "nsIDOMHTMLAnchorElement.h"
|
|
|
|
#include "nsIDOMHTMLInputElement.h"
|
|
|
|
#include "nsIDOMHTMLSelectElement.h"
|
|
|
|
#include "nsIDOMHTMLTextAreaElement.h"
|
1999-03-02 19:19:24 +00:00
|
|
|
#include "nsIDOMHTMLAreaElement.h"
|
|
|
|
#include "nsIDOMHTMLButtonElement.h"
|
|
|
|
#include "nsIDOMHTMLObjectElement.h"
|
|
|
|
#include "nsINameSpaceManager.h" // for kNameSpaceID_HTML
|
|
|
|
#include "nsIWebShell.h"
|
|
|
|
#include "nsIFocusableContent.h"
|
1999-04-30 19:38:39 +00:00
|
|
|
#include "nsIScrollableView.h"
|
1999-05-07 21:12:59 +00:00
|
|
|
#include "nsIDOMSelection.h"
|
|
|
|
#include "nsIFrameSelection.h"
|
1999-08-19 19:48:45 +00:00
|
|
|
#include "nsIDeviceContext.h"
|
1999-11-13 05:16:33 +00:00
|
|
|
#include "nsIScriptContextOwner.h"
|
|
|
|
#include "nsIScriptGlobalObject.h"
|
1999-11-21 01:46:41 +00:00
|
|
|
#include "nsISelfScrollingFrame.h"
|
1999-08-19 19:48:45 +00:00
|
|
|
|
1999-11-21 01:46:41 +00:00
|
|
|
#undef DEBUG_scroll // define to see ugly mousewheel messages
|
1998-06-23 21:53:02 +00:00
|
|
|
|
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
1998-11-18 05:25:26 +00:00
|
|
|
static NS_DEFINE_IID(kIDOMHTMLAnchorElementIID, NS_IDOMHTMLANCHORELEMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
|
1999-03-02 19:19:24 +00:00
|
|
|
static NS_DEFINE_IID(kIDOMHTMLAreaElementIID, NS_IDOMHTMLAREAELEMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMHTMLObjectElementIID, NS_IDOMHTMLOBJECTELEMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMHTMLButtonElementIID, NS_IDOMHTMLBUTTONELEMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
|
|
|
|
static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
|
1999-04-30 19:38:39 +00:00
|
|
|
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
|
1998-06-23 21:53:02 +00:00
|
|
|
|
1999-08-19 19:48:45 +00:00
|
|
|
nsEventStateManager::nsEventStateManager()
|
|
|
|
: mGestureDownPoint(0,0)
|
|
|
|
{
|
1998-11-18 05:25:26 +00:00
|
|
|
mLastMouseOverFrame = nsnull;
|
1999-05-04 14:44:51 +00:00
|
|
|
mLastDragOverFrame = nsnull;
|
1998-11-18 05:25:26 +00:00
|
|
|
mCurrentTarget = nsnull;
|
1999-06-15 03:14:28 +00:00
|
|
|
mCurrentTargetContent = nsnull;
|
1999-11-03 07:11:45 +00:00
|
|
|
mCurrentRelatedContent = nsnull;
|
1999-03-28 22:22:54 +00:00
|
|
|
mLastLeftMouseDownContent = nsnull;
|
|
|
|
mLastMiddleMouseDownContent = nsnull;
|
|
|
|
mLastRightMouseDownContent = nsnull;
|
1998-11-24 07:46:58 +00:00
|
|
|
|
1999-08-19 19:48:45 +00:00
|
|
|
// init d&d gesture state machine variables
|
|
|
|
mIsTrackingDragGesture = PR_FALSE;
|
|
|
|
mGestureDownFrame = nsnull;
|
|
|
|
|
1999-09-22 02:29:33 +00:00
|
|
|
mLClickCount = 0;
|
|
|
|
mMClickCount = 0;
|
|
|
|
mRClickCount = 0;
|
1999-03-28 22:22:54 +00:00
|
|
|
mActiveContent = nsnull;
|
|
|
|
mHoverContent = nsnull;
|
1999-05-04 14:44:51 +00:00
|
|
|
mDragOverContent = nsnull;
|
1998-11-18 05:25:26 +00:00
|
|
|
mCurrentFocus = nsnull;
|
|
|
|
mDocument = nsnull;
|
|
|
|
mPresContext = nsnull;
|
1999-03-02 19:19:24 +00:00
|
|
|
mCurrentTabIndex = 0;
|
1999-09-20 22:18:57 +00:00
|
|
|
mLastWindowToHaveFocus = nsnull;
|
1999-09-30 11:40:42 +00:00
|
|
|
mConsumeFocusEvents = PR_FALSE;
|
1998-06-25 14:51:48 +00:00
|
|
|
NS_INIT_REFCNT();
|
1998-06-23 21:53:02 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 14:54:59 +00:00
|
|
|
nsEventStateManager::~nsEventStateManager()
|
|
|
|
{
|
1999-06-15 03:14:28 +00:00
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
1999-11-03 07:11:45 +00:00
|
|
|
NS_IF_RELEASE(mCurrentRelatedContent);
|
1999-09-16 14:54:59 +00:00
|
|
|
|
|
|
|
NS_IF_RELEASE(mLastLeftMouseDownContent);
|
|
|
|
NS_IF_RELEASE(mLastMiddleMouseDownContent);
|
|
|
|
NS_IF_RELEASE(mLastRightMouseDownContent);
|
|
|
|
|
1999-03-28 22:22:54 +00:00
|
|
|
NS_IF_RELEASE(mActiveContent);
|
|
|
|
NS_IF_RELEASE(mHoverContent);
|
1999-05-04 14:44:51 +00:00
|
|
|
NS_IF_RELEASE(mDragOverContent);
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_IF_RELEASE(mCurrentFocus);
|
1999-09-16 14:54:59 +00:00
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_IF_RELEASE(mDocument);
|
1999-09-20 22:18:57 +00:00
|
|
|
|
|
|
|
NS_IF_RELEASE(mLastWindowToHaveFocus);
|
1998-06-23 21:53:02 +00:00
|
|
|
}
|
|
|
|
|
1999-11-23 07:05:53 +00:00
|
|
|
NS_IMPL_ISUPPORTS1(nsEventStateManager, nsIEventStateManager)
|
1998-06-23 21:53:02 +00:00
|
|
|
|
1999-11-13 05:16:33 +00:00
|
|
|
// This must be the same across instances
|
|
|
|
static nsCOMPtr<nsIContent> mLastFocusedContent;
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
|
1998-11-18 05:25:26 +00:00
|
|
|
nsGUIEvent *aEvent,
|
|
|
|
nsIFrame* aTargetFrame,
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStatus* aStatus,
|
1999-06-15 03:14:28 +00:00
|
|
|
nsIView* aView)
|
1998-06-23 21:53:02 +00:00
|
|
|
{
|
1999-11-24 06:03:41 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aStatus);
|
|
|
|
NS_ENSURE_ARG(aPresContext);
|
1999-09-30 11:40:42 +00:00
|
|
|
// This is an experiement and may be temporary
|
|
|
|
// this consumes the very next focus event
|
|
|
|
if (mConsumeFocusEvents && aEvent->message == NS_GOTFOCUS) {
|
|
|
|
//mConsumeFocusEvents = PR_FALSE;
|
|
|
|
return NS_ERROR_FAILURE; // this should consume the event
|
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
mCurrentTarget = aTargetFrame;
|
1999-06-15 03:14:28 +00:00
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
1998-11-19 00:43:36 +00:00
|
|
|
|
|
|
|
nsFrameState state;
|
1999-09-02 07:22:47 +00:00
|
|
|
|
|
|
|
NS_ASSERTION(mCurrentTarget, "mCurrentTarget is null. this should not happen. see bug #13007");
|
|
|
|
if (!mCurrentTarget) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-02-10 04:17:06 +00:00
|
|
|
mCurrentTarget->GetFrameState(&state);
|
1998-11-19 00:43:36 +00:00
|
|
|
state |= NS_FRAME_EXTERNAL_REFERENCE;
|
|
|
|
mCurrentTarget->SetFrameState(state);
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
*aStatus = nsEventStatus_eIgnore;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
1999-09-02 07:22:47 +00:00
|
|
|
NS_ASSERTION(aEvent, "aEvent is null. this should never happen");
|
|
|
|
if (!aEvent) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
switch (aEvent->message) {
|
1999-08-19 19:48:45 +00:00
|
|
|
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
|
|
|
BeginTrackingDragGesture ( aEvent, aTargetFrame );
|
1999-09-22 02:29:33 +00:00
|
|
|
mLClickCount = ((nsMouseEvent*)aEvent)->clickCount;
|
|
|
|
SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
|
|
|
break;
|
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
|
|
|
mMClickCount = ((nsMouseEvent*)aEvent)->clickCount;
|
|
|
|
SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
|
|
|
break;
|
|
|
|
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
|
|
|
mRClickCount = ((nsMouseEvent*)aEvent)->clickCount;
|
|
|
|
SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
1999-08-19 19:48:45 +00:00
|
|
|
break;
|
|
|
|
case NS_MOUSE_LEFT_BUTTON_UP:
|
|
|
|
StopTrackingDragGesture();
|
1999-09-22 02:29:33 +00:00
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
|
|
|
case NS_MOUSE_RIGHT_BUTTON_UP:
|
|
|
|
SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
1999-08-19 19:48:45 +00:00
|
|
|
break;
|
1998-11-18 05:25:26 +00:00
|
|
|
case NS_MOUSE_MOVE:
|
1999-08-19 19:48:45 +00:00
|
|
|
GenerateDragGesture(aPresContext, aEvent);
|
1998-12-03 03:07:16 +00:00
|
|
|
UpdateCursor(aPresContext, aEvent->point, aTargetFrame, aStatus);
|
1998-12-02 02:14:58 +00:00
|
|
|
GenerateMouseEnterExit(aPresContext, aEvent);
|
1998-11-18 05:25:26 +00:00
|
|
|
break;
|
|
|
|
case NS_MOUSE_EXIT:
|
1999-03-28 22:22:54 +00:00
|
|
|
GenerateMouseEnterExit(aPresContext, aEvent);
|
1998-11-18 05:25:26 +00:00
|
|
|
break;
|
1999-06-22 14:20:14 +00:00
|
|
|
case NS_DRAGDROP_OVER:
|
|
|
|
GenerateDragDropEnterExit(aPresContext, aEvent);
|
|
|
|
break;
|
1998-11-18 05:25:26 +00:00
|
|
|
case NS_GOTFOCUS:
|
1999-11-13 05:16:33 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIContent> oldFocusedContent;
|
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(oldFocusedContent));
|
|
|
|
if(mLastFocusedContent == oldFocusedContent)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// ask focus target about its CSS user-focus style
|
|
|
|
PRBool surpressBlurAndFocus = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIStyleContext> context;
|
|
|
|
mCurrentTarget->GetStyleContext(getter_AddRefs(context));
|
|
|
|
|
|
|
|
const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface);
|
|
|
|
if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) {
|
|
|
|
// we want to surpress the blur and the following focus based on user-focus: ignore;
|
|
|
|
surpressBlurAndFocus = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!surpressBlurAndFocus) {
|
|
|
|
// TODO: fire blur only if the focus target is not a child of the currently focused node
|
|
|
|
// (it would just get focus again a second later)
|
|
|
|
PRBool isChild = PR_FALSE;
|
|
|
|
|
|
|
|
if(!isChild){
|
|
|
|
// Ask if the last focused content can accept blur
|
|
|
|
nsCOMPtr<nsIContent> oldFocus = mLastFocusedContent;
|
|
|
|
if (oldFocus) {
|
|
|
|
nsIFocusableContent *focusChange;
|
|
|
|
if (NS_SUCCEEDED(oldFocus->QueryInterface(kIFocusableContentIID, (void **)&focusChange))) {
|
|
|
|
NS_RELEASE(focusChange);
|
|
|
|
|
|
|
|
//fire blur only if target can accept focus
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
|
|
|
|
|
|
|
if (!mDocument) {
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
1999-11-24 06:03:41 +00:00
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
1999-11-13 05:16:33 +00:00
|
|
|
if (presShell) {
|
|
|
|
presShell->GetDocument(&mDocument);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mDocument) {
|
|
|
|
mCurrentTarget = nsnull;
|
|
|
|
|
1999-11-29 22:47:39 +00:00
|
|
|
nsCOMPtr<nsIScriptContextOwner> contextOwner = getter_AddRefs(mDocument->GetScriptContextOwner());
|
1999-11-13 05:16:33 +00:00
|
|
|
if(!contextOwner) break;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
if(!globalObject) break;
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
globalObject->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-11-13 05:16:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ask if target can accept focus
|
|
|
|
mCurrentTarget = aTargetFrame;
|
|
|
|
|
|
|
|
//fire focus
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent focusevent;
|
|
|
|
focusevent.eventStructType = NS_EVENT;
|
|
|
|
focusevent.message = NS_FOCUS_CONTENT;
|
|
|
|
|
|
|
|
if (!mDocument) {
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
1999-11-24 06:03:41 +00:00
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
1999-11-13 05:16:33 +00:00
|
|
|
if (presShell) {
|
|
|
|
presShell->GetDocument(&mDocument);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mDocument) {
|
|
|
|
nsCOMPtr<nsIContent> newFoo;
|
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(newFoo));
|
|
|
|
mLastFocusedContent = newFoo;
|
|
|
|
|
|
|
|
mCurrentTarget = nsnull;
|
|
|
|
// fire focus on window, not document
|
|
|
|
nsCOMPtr<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
|
|
|
|
if(!contextOwner) break;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
if(!globalObject) break;
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
globalObject->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
mDocument->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-11-13 05:16:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_LOSTFOCUS:
|
|
|
|
{
|
|
|
|
// Hold the blur, wait for the focus so we can query the style of the focus
|
|
|
|
// target as to what to do with the event. If appropriate we fire the blur
|
|
|
|
// at that time.
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_ACTIVATE:
|
1999-07-27 20:55:03 +00:00
|
|
|
{
|
|
|
|
nsIContent* newFocus;
|
|
|
|
mCurrentTarget->GetContent(&newFocus);
|
|
|
|
if (newFocus) {
|
|
|
|
nsIFocusableContent *focusChange;
|
|
|
|
if (NS_SUCCEEDED(newFocus->QueryInterface(kIFocusableContentIID,
|
|
|
|
(void **)&focusChange))) {
|
|
|
|
NS_RELEASE(focusChange);
|
|
|
|
NS_RELEASE(newFocus);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
NS_RELEASE(newFocus);
|
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
|
1999-07-27 20:55:03 +00:00
|
|
|
//fire focus
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
1999-11-13 05:16:33 +00:00
|
|
|
nsEvent focusevent;
|
|
|
|
focusevent.eventStructType = NS_EVENT;
|
|
|
|
focusevent.message = NS_FOCUS_CONTENT;
|
1999-07-27 20:55:03 +00:00
|
|
|
|
|
|
|
if (!mDocument) {
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
1999-11-24 06:03:41 +00:00
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
1999-07-27 20:55:03 +00:00
|
|
|
if (presShell) {
|
|
|
|
presShell->GetDocument(&mDocument);
|
|
|
|
}
|
1999-06-15 03:14:28 +00:00
|
|
|
}
|
1999-07-27 20:55:03 +00:00
|
|
|
|
|
|
|
if (mDocument) {
|
1999-11-13 05:16:33 +00:00
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(mLastFocusedContent));
|
|
|
|
|
1999-07-27 20:55:03 +00:00
|
|
|
mCurrentTarget = nsnull;
|
1999-11-13 05:16:33 +00:00
|
|
|
|
|
|
|
// fire focus on window, not document
|
|
|
|
nsCOMPtr<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
|
|
|
|
if(!contextOwner) break;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
if(!globalObject) break;
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
globalObject->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-06-15 03:14:28 +00:00
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
|
1999-06-15 03:14:28 +00:00
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
break;
|
1999-11-13 05:16:33 +00:00
|
|
|
|
|
|
|
case NS_DEACTIVATE:
|
1999-07-27 20:55:03 +00:00
|
|
|
{
|
1999-11-13 05:16:33 +00:00
|
|
|
nsIContent* newFocus;
|
|
|
|
mCurrentTarget->GetContent(&newFocus);
|
|
|
|
if (newFocus) {
|
1999-07-27 20:55:03 +00:00
|
|
|
nsIFocusableContent *focusChange;
|
1999-11-13 05:16:33 +00:00
|
|
|
if (NS_SUCCEEDED(newFocus->QueryInterface(kIFocusableContentIID,
|
1999-07-27 20:55:03 +00:00
|
|
|
(void **)&focusChange))) {
|
|
|
|
NS_RELEASE(focusChange);
|
1999-11-13 05:16:33 +00:00
|
|
|
NS_RELEASE(newFocus);
|
1999-07-27 20:55:03 +00:00
|
|
|
break;
|
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
NS_RELEASE(newFocus);
|
1999-07-27 20:55:03 +00:00
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
|
|
|
|
//fire blur
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
|
|
|
|
|
|
|
if (!mDocument) {
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
1999-11-24 06:03:41 +00:00
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
1999-11-13 05:16:33 +00:00
|
|
|
if (presShell) {
|
|
|
|
presShell->GetDocument(&mDocument);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mDocument) {
|
|
|
|
mCurrentTarget = nsnull;
|
|
|
|
|
|
|
|
// fire focus on window, not document
|
|
|
|
nsCOMPtr<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
|
|
|
|
if(!contextOwner) break;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
if(!globalObject) break;
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
globalObject->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-11-13 05:16:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
1999-05-18 23:51:04 +00:00
|
|
|
break;
|
1999-11-13 05:16:33 +00:00
|
|
|
|
1999-07-27 14:38:07 +00:00
|
|
|
case NS_KEY_PRESS:
|
1999-07-27 20:55:03 +00:00
|
|
|
case NS_KEY_DOWN:
|
|
|
|
case NS_KEY_UP:
|
1999-11-21 01:46:41 +00:00
|
|
|
case NS_MOUSE_SCROLL:
|
1999-07-27 14:38:07 +00:00
|
|
|
{
|
1999-07-27 20:55:03 +00:00
|
|
|
if (mCurrentFocus) {
|
|
|
|
mCurrentTargetContent = mCurrentFocus;
|
|
|
|
NS_ADDREF(mCurrentTargetContent);
|
|
|
|
}
|
1999-07-27 14:38:07 +00:00
|
|
|
}
|
|
|
|
break;
|
1998-06-23 21:53:02 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-08-19 19:48:45 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// BeginTrackingDragGesture
|
|
|
|
//
|
|
|
|
// Record that the mouse has gone down and that we should move to TRACKING state
|
|
|
|
// of d&d gesture tracker.
|
|
|
|
//
|
|
|
|
void
|
|
|
|
nsEventStateManager :: BeginTrackingDragGesture ( nsGUIEvent* inDownEvent, nsIFrame* inDownFrame )
|
|
|
|
{
|
|
|
|
mIsTrackingDragGesture = PR_TRUE;
|
|
|
|
mGestureDownPoint = inDownEvent->point;
|
|
|
|
mGestureDownFrame = inDownFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// StopTrackingDragGesture
|
|
|
|
//
|
|
|
|
// Record that the mouse has gone back up so that we should leave the TRACKING
|
|
|
|
// state of d&d gesture tracker and return to the START state.
|
|
|
|
//
|
|
|
|
void
|
|
|
|
nsEventStateManager :: StopTrackingDragGesture ( )
|
|
|
|
{
|
|
|
|
mIsTrackingDragGesture = PR_FALSE;
|
|
|
|
mGestureDownPoint = nsPoint(0,0);
|
|
|
|
mGestureDownFrame = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// GenerateDragGesture
|
|
|
|
//
|
|
|
|
// If we're in the TRACKING state of the d&d gesture tracker, check the current position
|
|
|
|
// of the mouse in relation to the old one. If we've moved a sufficient amount from
|
|
|
|
// the mouse down, then fire off a drag gesture event.
|
|
|
|
//
|
|
|
|
// Note that when the mouse enters a new child window with its own view, the event's
|
|
|
|
// coordinates will be in relation to the origin of the inner child window, which could
|
|
|
|
// either be very different from that of the mouse coords of the mouse down and trigger
|
|
|
|
// a drag too early, or very similiar which might not trigger a drag.
|
|
|
|
//
|
|
|
|
// Do we need to do anything about this? Let's wait and see.
|
|
|
|
//
|
|
|
|
void
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager :: GenerateDragGesture ( nsIPresContext* aPresContext, nsGUIEvent *aEvent )
|
1999-08-19 19:48:45 +00:00
|
|
|
{
|
1999-11-24 06:03:41 +00:00
|
|
|
NS_WARN_IF_FALSE(aPresContext, "This shouldn't happen.");
|
1999-08-19 19:48:45 +00:00
|
|
|
if ( IsTrackingDragGesture() ) {
|
|
|
|
// figure out the delta in twips, since that is how it is in the event.
|
|
|
|
// Do we need to do this conversion every time? Will the pres context really change on
|
|
|
|
// us or can we cache it?
|
|
|
|
long twipDeltaToStartDrag = 0;
|
|
|
|
const long pixelDeltaToStartDrag = 5;
|
|
|
|
nsCOMPtr<nsIDeviceContext> devContext;
|
1999-11-24 06:03:41 +00:00
|
|
|
aPresContext->GetDeviceContext ( getter_AddRefs(devContext) );
|
1999-08-19 19:48:45 +00:00
|
|
|
if ( devContext ) {
|
|
|
|
float pixelsToTwips = 0.0;
|
|
|
|
devContext->GetDevUnitsToTwips(pixelsToTwips);
|
1999-08-24 09:37:28 +00:00
|
|
|
twipDeltaToStartDrag = (long)(pixelDeltaToStartDrag * pixelsToTwips);
|
1999-08-19 19:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// fire drag gesture if mouse has moved enough
|
|
|
|
if ( abs(aEvent->point.x - mGestureDownPoint.x) > twipDeltaToStartDrag ||
|
|
|
|
abs(aEvent->point.y - mGestureDownPoint.y) > twipDeltaToStartDrag ) {
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_DRAGDROP_EVENT;
|
|
|
|
event.message = NS_DRAGDROP_GESTURE;
|
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
|
|
|
|
|
|
|
// dispatch to the DOM
|
|
|
|
nsCOMPtr<nsIContent> lastContent;
|
1999-11-09 07:10:46 +00:00
|
|
|
if ( mGestureDownFrame ) {
|
|
|
|
mGestureDownFrame->GetContent(getter_AddRefs(lastContent));
|
|
|
|
if ( lastContent )
|
1999-11-24 06:03:41 +00:00
|
|
|
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-11-09 07:10:46 +00:00
|
|
|
}
|
|
|
|
|
1999-08-19 19:48:45 +00:00
|
|
|
// dispatch to the frame
|
1999-11-02 03:55:14 +00:00
|
|
|
if ( mGestureDownFrame )
|
1999-11-24 06:03:41 +00:00
|
|
|
mGestureDownFrame->HandleEvent(aPresContext, &event, &status);
|
1999-08-19 19:48:45 +00:00
|
|
|
|
|
|
|
StopTrackingDragGesture();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // GenerateDragGesture
|
|
|
|
|
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
|
1999-09-16 14:54:59 +00:00
|
|
|
nsGUIEvent *aEvent,
|
|
|
|
nsIFrame* aTargetFrame,
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStatus* aStatus,
|
1999-09-16 14:54:59 +00:00
|
|
|
nsIView* aView)
|
1998-11-24 07:46:58 +00:00
|
|
|
{
|
1999-11-24 06:03:41 +00:00
|
|
|
NS_ENSURE_ARG(aPresContext);
|
|
|
|
NS_ENSURE_ARG_POINTER(aStatus);
|
1998-11-24 07:46:58 +00:00
|
|
|
mCurrentTarget = aTargetFrame;
|
1999-06-15 03:14:28 +00:00
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
1998-11-24 07:46:58 +00:00
|
|
|
nsresult ret = NS_OK;
|
|
|
|
|
|
|
|
nsFrameState state;
|
1999-02-10 04:17:06 +00:00
|
|
|
mCurrentTarget->GetFrameState(&state);
|
1998-11-24 07:46:58 +00:00
|
|
|
state |= NS_FRAME_EXTERNAL_REFERENCE;
|
|
|
|
mCurrentTarget->SetFrameState(state);
|
|
|
|
|
|
|
|
switch (aEvent->message) {
|
|
|
|
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
1999-01-28 23:14:36 +00:00
|
|
|
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
|
|
|
{
|
1999-11-24 06:03:41 +00:00
|
|
|
if (nsEventStatus_eConsumeNoDefault != *aStatus) {
|
1999-09-30 11:40:42 +00:00
|
|
|
nsCOMPtr<nsIContent> newFocus;
|
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(newFocus));
|
1999-08-24 00:42:38 +00:00
|
|
|
nsCOMPtr<nsIFocusableContent> focusable;
|
|
|
|
|
1999-04-12 21:24:07 +00:00
|
|
|
if (newFocus) {
|
1999-08-24 00:42:38 +00:00
|
|
|
// Look for the nearest enclosing focusable content.
|
1999-09-30 11:40:42 +00:00
|
|
|
nsCOMPtr<nsIContent> current = newFocus;
|
1999-08-24 00:42:38 +00:00
|
|
|
while (current) {
|
|
|
|
focusable = do_QueryInterface(current);
|
|
|
|
if (focusable)
|
|
|
|
break;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> parent;
|
|
|
|
current->GetParent(*getter_AddRefs(parent));
|
|
|
|
current = parent;
|
|
|
|
}
|
1999-09-30 11:40:42 +00:00
|
|
|
|
|
|
|
// if a focusable piece of content is an anonymous node
|
|
|
|
// weed to find the parent and have the parent be the
|
|
|
|
// new focusable node
|
|
|
|
//
|
|
|
|
// We fist to check here to see if the focused content
|
|
|
|
// is anonymous content
|
|
|
|
if (focusable) {
|
|
|
|
nsCOMPtr<nsIContent> parent;
|
|
|
|
current->GetParent(*getter_AddRefs(parent));
|
|
|
|
NS_ASSERTION(parent.get(), "parent is null. this should not happen.");
|
|
|
|
PRInt32 numChilds;
|
|
|
|
parent->ChildCount(numChilds);
|
|
|
|
PRInt32 i;
|
|
|
|
PRBool isChild = PR_FALSE;
|
|
|
|
for (i=0;i<numChilds;i++) {
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
parent->ChildAt(i, *getter_AddRefs(child));
|
|
|
|
if (child.get() == current.get()) {
|
|
|
|
isChild = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// if it isn't a child of the parent, then it is anonynous content
|
|
|
|
// Now, go up the parent list to find a focusable content node
|
|
|
|
if (!isChild) {
|
|
|
|
current = parent;
|
|
|
|
while (current) {
|
|
|
|
focusable = do_QueryInterface(current);
|
|
|
|
if (focusable)
|
|
|
|
break;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> tempParent;
|
|
|
|
current->GetParent(*getter_AddRefs(tempParent));
|
|
|
|
current = tempParent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// now we ned to get the content node's frame and reset
|
|
|
|
// the mCurrentTarget target
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
if (mPresContext) {
|
|
|
|
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
if (NS_SUCCEEDED(rv) && shell){
|
|
|
|
shell->GetPrimaryFrameFor(current, &mCurrentTarget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// now adjust the value for the "newFocus"
|
|
|
|
newFocus = current;
|
|
|
|
}
|
|
|
|
|
1999-08-24 09:37:28 +00:00
|
|
|
PRBool focusChangeFailed = PR_TRUE;
|
1999-08-24 00:42:38 +00:00
|
|
|
if (focusable) {
|
1999-09-20 22:56:32 +00:00
|
|
|
if (current.get() != mCurrentFocus) {
|
1999-09-20 22:18:57 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryInterface(focusable);
|
1999-11-13 05:16:33 +00:00
|
|
|
if (ChangeFocus(content, mCurrentTarget, PR_TRUE))
|
1999-09-20 22:18:57 +00:00
|
|
|
focusChangeFailed = PR_FALSE;
|
|
|
|
} else {
|
1999-08-24 09:37:28 +00:00
|
|
|
focusChangeFailed = PR_FALSE;
|
1999-09-20 22:18:57 +00:00
|
|
|
}
|
1999-08-24 09:37:28 +00:00
|
|
|
}
|
|
|
|
|
1999-11-13 05:16:33 +00:00
|
|
|
// ask focus target the magic question
|
|
|
|
PRBool surpressBlurAndFocus = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIStyleContext> context;
|
|
|
|
|
|
|
|
if(!mCurrentTarget) break;
|
|
|
|
mCurrentTarget->GetStyleContext(getter_AddRefs(context));
|
|
|
|
if(!context) break;
|
|
|
|
|
|
|
|
const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface);
|
|
|
|
if(!styleStruct) break;
|
|
|
|
|
|
|
|
if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) {
|
|
|
|
// we want to surpress the blur and the following focus
|
|
|
|
surpressBlurAndFocus = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!surpressBlurAndFocus) {
|
1999-08-24 09:37:28 +00:00
|
|
|
if (nsnull != aEvent->widget) {
|
|
|
|
aEvent->widget->SetFocus();
|
1999-04-12 21:24:07 +00:00
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
if (focusChangeFailed) {
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
|
|
|
}
|
1999-04-12 21:24:07 +00:00
|
|
|
SetContentState(newFocus, NS_EVENT_STATE_ACTIVE);
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
1999-01-08 21:13:59 +00:00
|
|
|
}
|
1999-03-28 22:22:54 +00:00
|
|
|
break;
|
1998-11-24 07:46:58 +00:00
|
|
|
case NS_MOUSE_LEFT_BUTTON_UP:
|
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
|
|
|
case NS_MOUSE_RIGHT_BUTTON_UP:
|
1999-05-07 21:12:59 +00:00
|
|
|
{
|
|
|
|
ret = CheckForAndDispatchClick(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
1999-09-22 02:29:33 +00:00
|
|
|
|
1999-05-07 21:12:59 +00:00
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_ACTIVE);
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
1999-11-24 06:03:41 +00:00
|
|
|
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
|
1999-05-07 21:12:59 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && shell){
|
1999-07-18 02:27:19 +00:00
|
|
|
nsCOMPtr<nsIFrameSelection> frameSel;
|
|
|
|
rv = shell->GetFrameSelection(getter_AddRefs(frameSel));
|
|
|
|
if (NS_SUCCEEDED(rv) && frameSel){
|
1999-05-07 21:12:59 +00:00
|
|
|
frameSel->SetMouseDownState(PR_FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-11-24 07:46:58 +00:00
|
|
|
break;
|
1999-11-21 01:46:41 +00:00
|
|
|
case NS_MOUSE_SCROLL:
|
1999-11-24 06:03:41 +00:00
|
|
|
if (nsEventStatus_eConsumeNoDefault != *aStatus) {
|
1999-11-21 01:46:41 +00:00
|
|
|
|
|
|
|
nsIFrame* focusFrame = nsnull;
|
|
|
|
nsIView* focusView = nsnull;
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
1999-11-21 01:46:41 +00:00
|
|
|
if(!presShell) // this is bad
|
|
|
|
break;
|
|
|
|
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("PostHandleEvent: aTargetFrame = %p, aView = %p\n",
|
|
|
|
aTargetFrame, aView);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (mCurrentFocus) {
|
|
|
|
// Something is focused
|
|
|
|
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("PostHandleEvent: mCurrentFocus = %p\n", mCurrentFocus);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
presShell->GetPrimaryFrameFor(mCurrentFocus, &focusFrame);
|
|
|
|
if (focusFrame)
|
1999-11-24 06:03:41 +00:00
|
|
|
focusFrame->GetView(aPresContext, &focusView);
|
1999-11-21 01:46:41 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (focusFrame) {
|
|
|
|
if (!focusView) {
|
|
|
|
// The focused frame doesn't have a view
|
|
|
|
// Revert to the parameters passed in
|
|
|
|
// XXX this might not be right
|
|
|
|
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("Could not get a view for the focused frame\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
focusFrame = aTargetFrame;
|
|
|
|
focusView = aView;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Focus is null. This means the main document has the focus,
|
|
|
|
// and we should scroll that.
|
|
|
|
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("PostHandleEvent: mCurrentFocus = NULL\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// We need to make an exception here if we can get a SelfScrollingFrame
|
|
|
|
// This needs reviewed
|
|
|
|
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("mLastFocusedContent = %p\n", mLastFocusedContent);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
nsISelfScrollingFrame* sf = GetNearestSelfScrollingFrame(aTargetFrame);
|
|
|
|
if (sf) {
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("Found a SelfScrollingFrame\n");
|
|
|
|
#endif
|
|
|
|
focusFrame = aTargetFrame;
|
|
|
|
focusView = aView;
|
|
|
|
} else {
|
|
|
|
focusFrame = GetDocumentFrame(aPresContext);
|
1999-11-24 06:03:41 +00:00
|
|
|
focusFrame->GetView(aPresContext, &focusView);
|
1999-11-21 01:46:41 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
if (focusView)
|
|
|
|
printf("Got view for document frame!\n");
|
|
|
|
else // hopefully we won't be here
|
|
|
|
printf("Couldn't get view for document frame\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("PostHandleEvent: focusFrame = %p, focusView = %p\n", focusFrame,
|
|
|
|
focusView);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
nsIScrollableView* sv = GetNearestScrollingView(focusView);
|
|
|
|
if (sv) {
|
|
|
|
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("Found a ScrollingView\n");
|
|
|
|
#endif
|
|
|
|
sv->ScrollByLines(((nsMouseScrollEvent*)aEvent)->deltaLines);
|
|
|
|
|
|
|
|
// force the update to happen now, otherwise multiple scrolls can
|
|
|
|
// occur before the update is processed. (bug #7354)
|
|
|
|
nsIViewManager* vm = nsnull;
|
|
|
|
if (NS_OK == focusView->GetViewManager(vm) && nsnull != vm) {
|
|
|
|
// I'd use Composite here, but it doesn't always work.
|
|
|
|
// vm->Composite();
|
|
|
|
nsIView* rootView = nsnull;
|
|
|
|
if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) {
|
|
|
|
nsIWidget* rootWidget = nsnull;
|
|
|
|
if (NS_OK == rootView->GetWidget(rootWidget) && nsnull != rootWidget) {
|
|
|
|
rootWidget->Update();
|
|
|
|
NS_RELEASE(rootWidget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("No scrolling view, looking for a scrolling frame\n");
|
|
|
|
#endif
|
|
|
|
nsISelfScrollingFrame* sf = GetNearestSelfScrollingFrame(focusFrame);
|
|
|
|
if (sf) {
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("Found a scrolling frame\n");
|
|
|
|
#endif
|
|
|
|
sf->ScrollByLines(aPresContext,
|
|
|
|
((nsMouseScrollEvent*)aEvent)->deltaLines);
|
|
|
|
// Do we need to do something here like above?
|
|
|
|
}
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
else
|
|
|
|
printf("Could not find a scrolling frame\n");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-11-12 01:02:14 +00:00
|
|
|
case NS_DRAGDROP_DROP:
|
|
|
|
case NS_DRAGDROP_EXIT:
|
|
|
|
// clean up after ourselves. make sure we do this _after_ the event, else we'll
|
|
|
|
// clean up too early!
|
|
|
|
GenerateDragDropEnterExit(aPresContext, aEvent);
|
|
|
|
break;
|
landing keyEvent_19991004_BRANCH
bugs # see the log of the check in into branch
author/reviewer:
mozilla/layout/base/src/nsRangeList.cpp brade/mjudge
mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp brade/ftang
mozilla/layout/events/src/nsDOMEvent.cpp brade/joki
mozilla/layout/events/src/nsEventStateManager.cpp brade/joki
mozilla/widget/public/nsGUIEvent.h akkana/ftang
mozilla/widget/src/windows/nsWindow.cpp ftang/mjudge
mozilla/widget/src/windows/nsWindow.h ftang/mjudge
mozilla/widget/src/mac/nsTextAreaWidget.cpp brade/ftang
mozilla/widget/src/mac/nsMacEventHandler.cpp brade/simon
mozilla/widget/src/xpwidgets/nsKeyBindMgr.cpp brade/ftang
mozilla/widget/src/gtk/nsGtkEventHandler.cpp akkana/?
mozilla/widget/src/gtk/nsWidget.cpp erik/ftang
mozilla/layout/xul/base/src/nsTreeCellFrame.cpp brade/ftang
mozilla/editor/base/nsEditorEventListeners.cpp brade/akkana
mozilla/editor/base/nsHTMLEditor.cpp brade/akkana
mozilla/rdf/content/src/nsXULKeyListener.cpp ftang/saari
fix the master bug- 15693
fix at least, but not limited to, the following bugs
10158,11956,6053,9333,10901,14348,6449,11845,13016,14410,15657,15307,15842,13856
1999-10-14 18:27:01 +00:00
|
|
|
case NS_KEY_PRESS:
|
1999-11-24 06:03:41 +00:00
|
|
|
if (nsEventStatus_eConsumeNoDefault != *aStatus) {
|
1999-11-22 19:45:13 +00:00
|
|
|
nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
|
|
|
|
//This is to prevent keyboard scrolling while alt modifier in use.
|
|
|
|
if (!keyEvent->isAlt) {
|
|
|
|
switch(keyEvent->keyCode) {
|
|
|
|
case NS_VK_TAB:
|
|
|
|
//Shift focus forward or back depending on shift key
|
|
|
|
ShiftFocus(!((nsInputEvent*)aEvent)->isShift);
|
1999-11-24 06:03:41 +00:00
|
|
|
*aStatus = nsEventStatus_eConsumeNoDefault;
|
1999-11-22 19:45:13 +00:00
|
|
|
break;
|
|
|
|
case NS_VK_PAGE_DOWN:
|
|
|
|
case NS_VK_PAGE_UP:
|
|
|
|
if (!mCurrentFocus) {
|
|
|
|
nsIScrollableView* sv = GetNearestScrollingView(aView);
|
|
|
|
if (sv) {
|
|
|
|
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
|
|
|
sv->ScrollByPages((keyEvent->keyCode != NS_VK_PAGE_UP) ? 1 : -1);
|
|
|
|
}
|
1999-09-21 14:18:52 +00:00
|
|
|
}
|
1999-11-22 19:45:13 +00:00
|
|
|
break;
|
|
|
|
case NS_VK_HOME:
|
|
|
|
case NS_VK_END:
|
|
|
|
if (!mCurrentFocus) {
|
|
|
|
nsIScrollableView* sv = GetNearestScrollingView(aView);
|
|
|
|
if (sv) {
|
|
|
|
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
|
|
|
sv->ScrollByWhole((keyEvent->keyCode != NS_VK_HOME) ? PR_FALSE : PR_TRUE);
|
1999-05-31 01:45:23 +00:00
|
|
|
}
|
1999-04-30 19:38:39 +00:00
|
|
|
}
|
1999-11-22 19:45:13 +00:00
|
|
|
break;
|
|
|
|
case NS_VK_DOWN:
|
|
|
|
case NS_VK_UP:
|
landing keyEvent_19991004_BRANCH
bugs # see the log of the check in into branch
author/reviewer:
mozilla/layout/base/src/nsRangeList.cpp brade/mjudge
mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp brade/ftang
mozilla/layout/events/src/nsDOMEvent.cpp brade/joki
mozilla/layout/events/src/nsEventStateManager.cpp brade/joki
mozilla/widget/public/nsGUIEvent.h akkana/ftang
mozilla/widget/src/windows/nsWindow.cpp ftang/mjudge
mozilla/widget/src/windows/nsWindow.h ftang/mjudge
mozilla/widget/src/mac/nsTextAreaWidget.cpp brade/ftang
mozilla/widget/src/mac/nsMacEventHandler.cpp brade/simon
mozilla/widget/src/xpwidgets/nsKeyBindMgr.cpp brade/ftang
mozilla/widget/src/gtk/nsGtkEventHandler.cpp akkana/?
mozilla/widget/src/gtk/nsWidget.cpp erik/ftang
mozilla/layout/xul/base/src/nsTreeCellFrame.cpp brade/ftang
mozilla/editor/base/nsEditorEventListeners.cpp brade/akkana
mozilla/editor/base/nsHTMLEditor.cpp brade/akkana
mozilla/rdf/content/src/nsXULKeyListener.cpp ftang/saari
fix the master bug- 15693
fix at least, but not limited to, the following bugs
10158,11956,6053,9333,10901,14348,6449,11845,13016,14410,15657,15307,15842,13856
1999-10-14 18:27:01 +00:00
|
|
|
if (!mCurrentFocus) {
|
|
|
|
nsIScrollableView* sv = GetNearestScrollingView(aView);
|
|
|
|
if (sv) {
|
1999-11-22 19:45:13 +00:00
|
|
|
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
|
|
|
sv->ScrollByLines((keyEvent->keyCode == NS_VK_DOWN) ? 1 : -1);
|
|
|
|
|
|
|
|
// force the update to happen now, otherwise multiple scrolls can
|
|
|
|
// occur before the update is processed. (bug #7354)
|
|
|
|
nsIViewManager* vm = nsnull;
|
|
|
|
if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) {
|
|
|
|
// I'd use Composite here, but it doesn't always work.
|
|
|
|
// vm->Composite();
|
|
|
|
nsIView* rootView = nsnull;
|
|
|
|
if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) {
|
|
|
|
nsIWidget* rootWidget = nsnull;
|
|
|
|
if (NS_OK == rootView->GetWidget(rootWidget) && nsnull != rootWidget) {
|
|
|
|
rootWidget->Update();
|
|
|
|
NS_RELEASE(rootWidget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0: /* check charcode since keycode is 0 */
|
|
|
|
{
|
|
|
|
//Spacebar
|
|
|
|
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
|
|
|
if (keyEvent->charCode == 0x20) {
|
|
|
|
if (!mCurrentFocus) {
|
|
|
|
nsIScrollableView* sv = GetNearestScrollingView(aView);
|
|
|
|
if (sv) {
|
|
|
|
sv->ScrollByPages(1);
|
|
|
|
}
|
landing keyEvent_19991004_BRANCH
bugs # see the log of the check in into branch
author/reviewer:
mozilla/layout/base/src/nsRangeList.cpp brade/mjudge
mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp brade/ftang
mozilla/layout/events/src/nsDOMEvent.cpp brade/joki
mozilla/layout/events/src/nsEventStateManager.cpp brade/joki
mozilla/widget/public/nsGUIEvent.h akkana/ftang
mozilla/widget/src/windows/nsWindow.cpp ftang/mjudge
mozilla/widget/src/windows/nsWindow.h ftang/mjudge
mozilla/widget/src/mac/nsTextAreaWidget.cpp brade/ftang
mozilla/widget/src/mac/nsMacEventHandler.cpp brade/simon
mozilla/widget/src/xpwidgets/nsKeyBindMgr.cpp brade/ftang
mozilla/widget/src/gtk/nsGtkEventHandler.cpp akkana/?
mozilla/widget/src/gtk/nsWidget.cpp erik/ftang
mozilla/layout/xul/base/src/nsTreeCellFrame.cpp brade/ftang
mozilla/editor/base/nsEditorEventListeners.cpp brade/akkana
mozilla/editor/base/nsHTMLEditor.cpp brade/akkana
mozilla/rdf/content/src/nsXULKeyListener.cpp ftang/saari
fix the master bug- 15693
fix at least, but not limited to, the following bugs
10158,11956,6053,9333,10901,14348,6449,11845,13016,14410,15657,15307,15842,13856
1999-10-14 18:27:01 +00:00
|
|
|
}
|
|
|
|
}
|
1999-07-06 22:55:46 +00:00
|
|
|
}
|
1999-11-22 19:45:13 +00:00
|
|
|
break;
|
1999-07-06 22:55:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-11-24 07:46:58 +00:00
|
|
|
}
|
1999-11-03 07:11:45 +00:00
|
|
|
|
1999-11-08 21:30:22 +00:00
|
|
|
//Reset target frame to null to avoid mistargetting after reentrant event
|
|
|
|
mCurrentTarget = nsnull;
|
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::SetPresContext(nsIPresContext* aPresContext)
|
1998-06-23 21:53:02 +00:00
|
|
|
{
|
1998-11-18 05:25:26 +00:00
|
|
|
mPresContext = aPresContext;
|
1998-07-17 04:52:12 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-11-19 00:43:36 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::ClearFrameRefs(nsIFrame* aFrame)
|
|
|
|
{
|
1999-11-02 03:55:14 +00:00
|
|
|
if (aFrame == mLastMouseOverFrame)
|
1998-11-19 00:43:36 +00:00
|
|
|
mLastMouseOverFrame = nsnull;
|
1999-11-02 03:55:14 +00:00
|
|
|
if (aFrame == mLastDragOverFrame)
|
|
|
|
mLastDragOverFrame = nsnull;
|
|
|
|
if (aFrame == mGestureDownFrame)
|
|
|
|
mGestureDownFrame = nsnull;
|
1998-11-24 07:46:58 +00:00
|
|
|
if (aFrame == mCurrentTarget) {
|
1999-06-15 03:14:28 +00:00
|
|
|
if (aFrame) {
|
|
|
|
aFrame->GetContent(&mCurrentTargetContent);
|
|
|
|
}
|
1998-11-19 00:43:36 +00:00
|
|
|
mCurrentTarget = nsnull;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-30 19:38:39 +00:00
|
|
|
nsIScrollableView*
|
|
|
|
nsEventStateManager::GetNearestScrollingView(nsIView* aView)
|
|
|
|
{
|
|
|
|
nsIScrollableView* sv;
|
|
|
|
if (NS_OK == aView->QueryInterface(kIScrollableViewIID, (void**)&sv)) {
|
|
|
|
return sv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIView* parent;
|
|
|
|
aView->GetParent(parent);
|
|
|
|
|
|
|
|
if (nsnull != parent) {
|
|
|
|
return GetNearestScrollingView(parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
1999-11-21 01:46:41 +00:00
|
|
|
nsISelfScrollingFrame*
|
|
|
|
nsEventStateManager::GetNearestSelfScrollingFrame(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
nsISelfScrollingFrame *sf;
|
|
|
|
if (NS_OK == aFrame->QueryInterface(NS_GET_IID(nsISelfScrollingFrame),
|
|
|
|
(void**)&sf)) {
|
|
|
|
return sf;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIFrame* parent;
|
|
|
|
aFrame->GetParent(&parent);
|
|
|
|
|
|
|
|
if (nsnull != parent) {
|
|
|
|
return GetNearestSelfScrollingFrame(parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
void
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::UpdateCursor(nsIPresContext* aPresContext, nsPoint& aPoint, nsIFrame* aTargetFrame,
|
|
|
|
nsEventStatus* aStatus)
|
1998-07-17 04:52:12 +00:00
|
|
|
{
|
1998-11-18 05:25:26 +00:00
|
|
|
PRInt32 cursor;
|
|
|
|
nsCursor c;
|
|
|
|
|
|
|
|
aTargetFrame->GetCursor(aPresContext, aPoint, cursor);
|
|
|
|
|
|
|
|
switch (cursor) {
|
|
|
|
default:
|
|
|
|
case NS_STYLE_CURSOR_AUTO:
|
|
|
|
case NS_STYLE_CURSOR_DEFAULT:
|
|
|
|
c = eCursor_standard;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_POINTER:
|
|
|
|
c = eCursor_hyperlink;
|
|
|
|
break;
|
1999-07-07 07:50:03 +00:00
|
|
|
case NS_STYLE_CURSOR_CROSSHAIR:
|
|
|
|
c = eCursor_crosshair;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_MOVE:
|
|
|
|
c = eCursor_move;
|
|
|
|
break;
|
1998-11-18 05:25:26 +00:00
|
|
|
case NS_STYLE_CURSOR_TEXT:
|
|
|
|
c = eCursor_select;
|
|
|
|
break;
|
1999-07-07 07:50:03 +00:00
|
|
|
case NS_STYLE_CURSOR_WAIT:
|
|
|
|
c = eCursor_wait;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_HELP:
|
|
|
|
c = eCursor_help;
|
|
|
|
break;
|
1998-11-18 05:25:26 +00:00
|
|
|
case NS_STYLE_CURSOR_N_RESIZE:
|
|
|
|
case NS_STYLE_CURSOR_S_RESIZE:
|
|
|
|
c = eCursor_sizeNS;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_W_RESIZE:
|
|
|
|
case NS_STYLE_CURSOR_E_RESIZE:
|
|
|
|
c = eCursor_sizeWE;
|
|
|
|
break;
|
1999-07-07 07:50:03 +00:00
|
|
|
//These aren't in the CSS2 spec. Don't know what to do with them.
|
1998-11-18 05:25:26 +00:00
|
|
|
case NS_STYLE_CURSOR_NE_RESIZE:
|
|
|
|
case NS_STYLE_CURSOR_NW_RESIZE:
|
|
|
|
case NS_STYLE_CURSOR_SE_RESIZE:
|
|
|
|
case NS_STYLE_CURSOR_SW_RESIZE:
|
|
|
|
c = eCursor_select;
|
|
|
|
break;
|
1998-07-17 04:52:12 +00:00
|
|
|
}
|
1998-12-03 03:07:16 +00:00
|
|
|
|
|
|
|
if (NS_STYLE_CURSOR_AUTO != cursor) {
|
1999-11-24 06:03:41 +00:00
|
|
|
*aStatus = nsEventStatus_eConsumeDoDefault;
|
1998-12-03 03:07:16 +00:00
|
|
|
}
|
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
nsCOMPtr<nsIWidget> window;
|
1999-11-24 06:03:41 +00:00
|
|
|
aTargetFrame->GetWindow(aPresContext, getter_AddRefs(window));
|
1998-11-18 05:25:26 +00:00
|
|
|
window->SetCursor(c);
|
1998-07-17 04:52:12 +00:00
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
void
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIEvent* aEvent)
|
1998-07-17 04:52:12 +00:00
|
|
|
{
|
1999-11-03 07:11:45 +00:00
|
|
|
//Hold onto old target content through the event and reset after.
|
|
|
|
nsCOMPtr<nsIContent> targetBeforeEvent = mCurrentTargetContent;
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
switch(aEvent->message) {
|
|
|
|
case NS_MOUSE_MOVE:
|
|
|
|
{
|
1998-12-02 02:14:58 +00:00
|
|
|
if (mLastMouseOverFrame != mCurrentTarget) {
|
1998-11-18 05:25:26 +00:00
|
|
|
//We'll need the content, too, to check if it changed separately from the frames.
|
1999-11-02 03:55:14 +00:00
|
|
|
nsCOMPtr<nsIContent> lastContent;
|
|
|
|
nsCOMPtr<nsIContent> targetContent;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
1999-11-09 07:10:46 +00:00
|
|
|
if ( mCurrentTarget )
|
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(targetContent));
|
1998-11-18 05:25:26 +00:00
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
if (mLastMouseOverFrame) {
|
1998-11-18 05:25:26 +00:00
|
|
|
//fire mouseout
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_MOUSE_EVENT;
|
|
|
|
event.message = NS_MOUSE_EXIT;
|
1999-07-01 04:12:42 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
|
|
|
//The frame has change but the content may not have. Check before dispatching to content
|
1999-11-02 03:55:14 +00:00
|
|
|
mLastMouseOverFrame->GetContent(getter_AddRefs(lastContent));
|
1998-11-18 05:25:26 +00:00
|
|
|
|
1999-11-03 07:11:45 +00:00
|
|
|
mCurrentTargetContent = lastContent;
|
|
|
|
NS_IF_ADDREF(mCurrentTargetContent);
|
|
|
|
mCurrentRelatedContent = targetContent;
|
|
|
|
NS_IF_ADDREF(mCurrentRelatedContent);
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
if (lastContent != targetContent) {
|
1998-11-19 00:43:36 +00:00
|
|
|
//XXX This event should still go somewhere!!
|
|
|
|
if (nsnull != lastContent) {
|
1999-11-24 06:03:41 +00:00
|
|
|
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1998-11-19 00:43:36 +00:00
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Now dispatch to the frame
|
1999-11-02 03:55:14 +00:00
|
|
|
if (mLastMouseOverFrame) {
|
1999-01-28 23:14:36 +00:00
|
|
|
//XXX Get the new frame
|
1999-11-24 06:03:41 +00:00
|
|
|
mLastMouseOverFrame->HandleEvent(aPresContext, &event, &status);
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
1999-11-03 07:11:45 +00:00
|
|
|
|
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
|
|
|
NS_IF_RELEASE(mCurrentRelatedContent);
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//fire mouseover
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_MOUSE_EVENT;
|
|
|
|
event.message = NS_MOUSE_ENTER;
|
1999-07-01 04:12:42 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
1999-11-03 07:11:45 +00:00
|
|
|
mCurrentTargetContent = targetContent;
|
|
|
|
NS_IF_ADDREF(mCurrentTargetContent);
|
|
|
|
mCurrentRelatedContent = lastContent;
|
|
|
|
NS_IF_ADDREF(mCurrentRelatedContent);
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
//The frame has change but the content may not have. Check before dispatching to content
|
|
|
|
if (lastContent != targetContent) {
|
1998-11-19 00:43:36 +00:00
|
|
|
//XXX This event should still go somewhere!!
|
1999-11-02 03:55:14 +00:00
|
|
|
if (targetContent) {
|
1999-11-24 06:03:41 +00:00
|
|
|
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1998-11-19 00:43:36 +00:00
|
|
|
}
|
1999-04-12 21:24:07 +00:00
|
|
|
|
|
|
|
if (nsEventStatus_eConsumeNoDefault != status) {
|
|
|
|
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Now dispatch to the frame
|
1999-11-02 03:55:14 +00:00
|
|
|
if (mCurrentTarget) {
|
1999-01-28 23:14:36 +00:00
|
|
|
//XXX Get the new frame
|
1999-11-24 06:03:41 +00:00
|
|
|
mCurrentTarget->HandleEvent(aPresContext, &event, &status);
|
1998-12-02 02:14:58 +00:00
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
|
1999-11-03 07:11:45 +00:00
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
|
|
|
NS_IF_RELEASE(mCurrentRelatedContent);
|
1998-12-02 02:14:58 +00:00
|
|
|
mLastMouseOverFrame = mCurrentTarget;
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NS_MOUSE_EXIT:
|
|
|
|
{
|
1999-11-03 07:11:45 +00:00
|
|
|
//This is actually the window mouse exit event.
|
1998-11-18 05:25:26 +00:00
|
|
|
if (nsnull != mLastMouseOverFrame) {
|
|
|
|
//fire mouseout
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_MOUSE_EVENT;
|
|
|
|
event.message = NS_MOUSE_EXIT;
|
1999-07-01 04:12:42 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
nsCOMPtr<nsIContent> lastContent;
|
|
|
|
mLastMouseOverFrame->GetContent(getter_AddRefs(lastContent));
|
1998-11-18 05:25:26 +00:00
|
|
|
|
1999-11-03 07:11:45 +00:00
|
|
|
mCurrentTargetContent = lastContent;
|
|
|
|
NS_IF_ADDREF(mCurrentTargetContent);
|
|
|
|
mCurrentRelatedContent = nsnull;
|
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
if (lastContent) {
|
1999-11-24 06:03:41 +00:00
|
|
|
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-06-22 14:20:14 +00:00
|
|
|
|
|
|
|
if (nsEventStatus_eConsumeNoDefault != status) {
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_HOVER);
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
1999-06-22 14:20:14 +00:00
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
//Now dispatch to the frame
|
1999-01-28 23:14:36 +00:00
|
|
|
if (nsnull != mLastMouseOverFrame) {
|
|
|
|
//XXX Get the new frame
|
1999-11-24 06:03:41 +00:00
|
|
|
mLastMouseOverFrame->HandleEvent(aPresContext, &event, &status);
|
1999-06-22 14:20:14 +00:00
|
|
|
mLastMouseOverFrame = nsnull;
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
1999-11-03 07:11:45 +00:00
|
|
|
|
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
1999-11-03 07:11:45 +00:00
|
|
|
|
|
|
|
//reset mCurretTargetContent to what it was
|
|
|
|
mCurrentTargetContent = targetBeforeEvent;
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
1999-05-04 14:44:51 +00:00
|
|
|
void
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsGUIEvent* aEvent)
|
1999-05-04 14:44:51 +00:00
|
|
|
{
|
1999-11-03 07:11:45 +00:00
|
|
|
//Hold onto old target content through the event and reset after.
|
|
|
|
nsCOMPtr<nsIContent> targetBeforeEvent = mCurrentTargetContent;
|
|
|
|
|
1999-05-04 14:44:51 +00:00
|
|
|
switch(aEvent->message) {
|
|
|
|
case NS_DRAGDROP_OVER:
|
|
|
|
{
|
|
|
|
if (mLastDragOverFrame != mCurrentTarget) {
|
|
|
|
//We'll need the content, too, to check if it changed separately from the frames.
|
1999-11-02 03:55:14 +00:00
|
|
|
nsCOMPtr<nsIContent> lastContent;
|
|
|
|
nsCOMPtr<nsIContent> targetContent;
|
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(targetContent));
|
1999-05-04 14:44:51 +00:00
|
|
|
|
1999-09-09 00:28:23 +00:00
|
|
|
if ( mLastDragOverFrame ) {
|
|
|
|
//fire drag exit
|
1999-05-04 14:44:51 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_DRAGDROP_EVENT;
|
|
|
|
event.message = NS_DRAGDROP_EXIT;
|
1999-07-01 04:12:42 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1999-05-04 14:44:51 +00:00
|
|
|
|
|
|
|
//The frame has change but the content may not have. Check before dispatching to content
|
1999-11-02 03:55:14 +00:00
|
|
|
mLastDragOverFrame->GetContent(getter_AddRefs(lastContent));
|
1999-05-04 14:44:51 +00:00
|
|
|
|
1999-11-03 07:11:45 +00:00
|
|
|
mCurrentTargetContent = lastContent;
|
|
|
|
NS_IF_ADDREF(mCurrentTargetContent);
|
|
|
|
mCurrentRelatedContent = targetContent;
|
|
|
|
NS_IF_ADDREF(mCurrentRelatedContent);
|
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
if ( lastContent != targetContent ) {
|
1999-05-04 14:44:51 +00:00
|
|
|
//XXX This event should still go somewhere!!
|
1999-09-09 00:28:23 +00:00
|
|
|
if (lastContent)
|
1999-11-24 06:03:41 +00:00
|
|
|
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-05-04 14:44:51 +00:00
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
// clear the drag hover
|
|
|
|
if (status != nsEventStatus_eConsumeNoDefault )
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_DRAGOVER);
|
1999-05-04 14:44:51 +00:00
|
|
|
}
|
1999-11-02 03:55:14 +00:00
|
|
|
|
|
|
|
// Finally dispatch exit to the frame
|
1999-11-03 07:11:45 +00:00
|
|
|
if ( mLastDragOverFrame ) {
|
1999-11-24 06:03:41 +00:00
|
|
|
mLastDragOverFrame->HandleEvent(aPresContext, &event, &status);
|
1999-11-03 07:11:45 +00:00
|
|
|
|
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
|
|
|
NS_IF_RELEASE(mCurrentRelatedContent);
|
|
|
|
|
|
|
|
}
|
1999-05-04 14:44:51 +00:00
|
|
|
}
|
|
|
|
|
1999-09-09 00:28:23 +00:00
|
|
|
//fire drag enter
|
1999-05-04 14:44:51 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_DRAGDROP_EVENT;
|
|
|
|
event.message = NS_DRAGDROP_ENTER;
|
1999-07-01 04:12:42 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1999-05-04 14:44:51 +00:00
|
|
|
|
1999-11-03 07:11:45 +00:00
|
|
|
mCurrentTargetContent = targetContent;
|
|
|
|
NS_IF_ADDREF(mCurrentTargetContent);
|
|
|
|
mCurrentRelatedContent = lastContent;
|
|
|
|
NS_IF_ADDREF(mCurrentRelatedContent);
|
|
|
|
|
1999-05-04 14:44:51 +00:00
|
|
|
//The frame has change but the content may not have. Check before dispatching to content
|
1999-11-02 03:55:14 +00:00
|
|
|
if ( lastContent != targetContent ) {
|
1999-05-04 14:44:51 +00:00
|
|
|
//XXX This event should still go somewhere!!
|
1999-09-09 00:28:23 +00:00
|
|
|
if ( targetContent )
|
1999-11-24 06:03:41 +00:00
|
|
|
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-05-04 14:44:51 +00:00
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
// set drag hover on this frame
|
|
|
|
if ( status != nsEventStatus_eConsumeNoDefault )
|
1999-05-04 14:44:51 +00:00
|
|
|
SetContentState(targetContent, NS_EVENT_STATE_DRAGOVER);
|
|
|
|
}
|
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
// Finally dispatch to the frame
|
1999-09-09 00:28:23 +00:00
|
|
|
if (mCurrentTarget) {
|
1999-05-04 14:44:51 +00:00
|
|
|
//XXX Get the new frame
|
1999-11-24 06:03:41 +00:00
|
|
|
mCurrentTarget->HandleEvent(aPresContext, &event, &status);
|
1999-05-04 14:44:51 +00:00
|
|
|
}
|
|
|
|
|
1999-11-03 07:11:45 +00:00
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
|
|
|
NS_IF_RELEASE(mCurrentRelatedContent);
|
1999-05-04 14:44:51 +00:00
|
|
|
mLastDragOverFrame = mCurrentTarget;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
1999-11-02 03:55:14 +00:00
|
|
|
|
1999-06-22 14:20:14 +00:00
|
|
|
case NS_DRAGDROP_DROP:
|
|
|
|
case NS_DRAGDROP_EXIT:
|
1999-05-04 14:44:51 +00:00
|
|
|
{
|
1999-11-03 07:11:45 +00:00
|
|
|
//This is actually the window mouse exit event.
|
1999-11-02 03:55:14 +00:00
|
|
|
if ( mLastDragOverFrame ) {
|
|
|
|
|
|
|
|
// fire mouseout
|
1999-05-04 14:44:51 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_DRAGDROP_EVENT;
|
|
|
|
event.message = NS_DRAGDROP_EXIT;
|
1999-07-01 04:12:42 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1999-05-04 14:44:51 +00:00
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
// dispatch to content via DOM
|
|
|
|
nsCOMPtr<nsIContent> lastContent;
|
|
|
|
mLastDragOverFrame->GetContent(getter_AddRefs(lastContent));
|
1999-11-03 07:11:45 +00:00
|
|
|
|
|
|
|
mCurrentTargetContent = lastContent;
|
|
|
|
NS_IF_ADDREF(mCurrentTargetContent);
|
|
|
|
mCurrentRelatedContent = nsnull;
|
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
if ( lastContent ) {
|
1999-11-24 06:03:41 +00:00
|
|
|
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-11-02 03:55:14 +00:00
|
|
|
if ( status != nsEventStatus_eConsumeNoDefault )
|
1999-06-22 14:20:14 +00:00
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_DRAGOVER);
|
1999-05-04 14:44:51 +00:00
|
|
|
}
|
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
// Finally dispatch to the frame
|
|
|
|
if ( mLastDragOverFrame ) {
|
1999-05-04 14:44:51 +00:00
|
|
|
//XXX Get the new frame
|
1999-11-24 06:03:41 +00:00
|
|
|
mLastDragOverFrame->HandleEvent(aPresContext, &event, &status);
|
1999-06-22 14:20:14 +00:00
|
|
|
mLastDragOverFrame = nsnull;
|
1999-05-04 14:44:51 +00:00
|
|
|
}
|
1999-11-03 07:11:45 +00:00
|
|
|
|
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
|
|
|
}
|
1999-05-04 14:44:51 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
1999-11-03 07:11:45 +00:00
|
|
|
|
|
|
|
//reset mCurretTargetContent to what it was
|
|
|
|
mCurrentTargetContent = targetBeforeEvent;
|
1999-05-04 14:44:51 +00:00
|
|
|
}
|
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::SetClickCount(nsIPresContext* aPresContext,
|
1999-09-22 02:29:33 +00:00
|
|
|
nsMouseEvent *aEvent,
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStatus* aStatus)
|
1998-11-24 07:46:58 +00:00
|
|
|
{
|
1999-03-11 05:56:11 +00:00
|
|
|
nsresult ret = NS_OK;
|
1999-09-16 14:54:59 +00:00
|
|
|
nsCOMPtr<nsIContent> mouseContent;
|
1998-11-24 07:46:58 +00:00
|
|
|
|
1999-09-16 14:54:59 +00:00
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(mouseContent));
|
1999-03-28 22:22:54 +00:00
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
switch (aEvent->message) {
|
|
|
|
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
1999-09-16 14:54:59 +00:00
|
|
|
NS_IF_RELEASE(mLastLeftMouseDownContent);
|
1999-03-28 22:22:54 +00:00
|
|
|
mLastLeftMouseDownContent = mouseContent;
|
|
|
|
NS_IF_ADDREF(mLastLeftMouseDownContent);
|
1998-11-24 07:46:58 +00:00
|
|
|
break;
|
1999-09-16 14:54:59 +00:00
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
case NS_MOUSE_LEFT_BUTTON_UP:
|
1999-09-16 14:54:59 +00:00
|
|
|
if (mLastLeftMouseDownContent == mouseContent.get()) {
|
1999-09-22 02:29:33 +00:00
|
|
|
aEvent->clickCount = mLClickCount;
|
|
|
|
mLClickCount = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aEvent->clickCount = 0;
|
1998-11-24 07:46:58 +00:00
|
|
|
}
|
1999-03-28 22:22:54 +00:00
|
|
|
NS_IF_RELEASE(mLastLeftMouseDownContent);
|
1998-11-24 07:46:58 +00:00
|
|
|
break;
|
1999-09-16 14:54:59 +00:00
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
1999-09-16 14:54:59 +00:00
|
|
|
NS_IF_RELEASE(mLastMiddleMouseDownContent);
|
1999-03-28 22:22:54 +00:00
|
|
|
mLastMiddleMouseDownContent = mouseContent;
|
|
|
|
NS_IF_ADDREF(mLastMiddleMouseDownContent);
|
1998-11-24 07:46:58 +00:00
|
|
|
break;
|
1999-09-16 14:54:59 +00:00
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
1999-09-16 14:54:59 +00:00
|
|
|
if (mLastMiddleMouseDownContent == mouseContent.get()) {
|
1999-09-22 02:29:33 +00:00
|
|
|
aEvent->clickCount = mMClickCount;
|
|
|
|
mMClickCount = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aEvent->clickCount = 0;
|
1998-11-24 07:46:58 +00:00
|
|
|
}
|
1999-03-28 22:22:54 +00:00
|
|
|
NS_IF_RELEASE(mLastMiddleMouseDownContent);
|
1998-11-24 07:46:58 +00:00
|
|
|
break;
|
1999-09-16 14:54:59 +00:00
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
1999-09-16 14:54:59 +00:00
|
|
|
NS_IF_RELEASE(mLastRightMouseDownContent);
|
1999-03-28 22:22:54 +00:00
|
|
|
mLastRightMouseDownContent = mouseContent;
|
|
|
|
NS_IF_ADDREF(mLastRightMouseDownContent);
|
1998-11-24 07:46:58 +00:00
|
|
|
break;
|
1999-09-16 14:54:59 +00:00
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
case NS_MOUSE_RIGHT_BUTTON_UP:
|
1999-09-16 14:54:59 +00:00
|
|
|
if (mLastRightMouseDownContent == mouseContent.get()) {
|
1999-09-22 02:29:33 +00:00
|
|
|
aEvent->clickCount = mRClickCount;
|
|
|
|
mRClickCount = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aEvent->clickCount = 0;
|
1998-11-24 07:46:58 +00:00
|
|
|
}
|
1999-03-28 22:22:54 +00:00
|
|
|
NS_IF_RELEASE(mLastRightMouseDownContent);
|
1998-11-24 07:46:58 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1999-09-22 02:29:33 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::CheckForAndDispatchClick(nsIPresContext* aPresContext,
|
1999-09-22 02:29:33 +00:00
|
|
|
nsMouseEvent *aEvent,
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStatus* aStatus)
|
1999-09-22 02:29:33 +00:00
|
|
|
{
|
|
|
|
nsresult ret = NS_OK;
|
|
|
|
nsMouseEvent event;
|
|
|
|
nsCOMPtr<nsIContent> mouseContent;
|
|
|
|
|
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(mouseContent));
|
|
|
|
|
|
|
|
//If mouse is still over same element, clickcount will be > 1.
|
|
|
|
//If it has moved it will be zero, so no click.
|
|
|
|
if (0 != aEvent->clickCount) {
|
1998-11-24 07:46:58 +00:00
|
|
|
//fire click
|
1999-09-22 02:29:33 +00:00
|
|
|
switch (aEvent->message) {
|
|
|
|
case NS_MOUSE_LEFT_BUTTON_UP:
|
|
|
|
event.message = NS_MOUSE_LEFT_CLICK;
|
|
|
|
break;
|
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
|
|
|
event.message = NS_MOUSE_MIDDLE_CLICK;
|
|
|
|
break;
|
|
|
|
case NS_MOUSE_RIGHT_BUTTON_UP:
|
|
|
|
event.message = NS_MOUSE_RIGHT_CLICK;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
event.eventStructType = NS_MOUSE_EVENT;
|
1999-06-09 07:38:26 +00:00
|
|
|
event.widget = aEvent->widget;
|
1999-06-08 19:28:52 +00:00
|
|
|
event.point.x = aEvent->point.x;
|
|
|
|
event.point.y = aEvent->point.y;
|
1999-06-09 07:38:26 +00:00
|
|
|
event.refPoint.x = aEvent->refPoint.x;
|
|
|
|
event.refPoint.y = aEvent->refPoint.y;
|
1999-09-22 02:29:33 +00:00
|
|
|
event.clickCount = aEvent->clickCount;
|
1998-11-24 07:46:58 +00:00
|
|
|
|
1999-09-16 14:54:59 +00:00
|
|
|
if (mouseContent) {
|
|
|
|
ret = mouseContent->HandleDOMEvent(aPresContext, &event, nsnull,
|
|
|
|
NS_EVENT_FLAG_INIT, aStatus);
|
1998-11-24 07:46:58 +00:00
|
|
|
}
|
1999-04-13 00:27:58 +00:00
|
|
|
|
|
|
|
if (nsnull != mCurrentTarget) {
|
|
|
|
ret = mCurrentTarget->HandleEvent(aPresContext, &event, aStatus);
|
|
|
|
}
|
1998-11-24 07:46:58 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::DispatchKeyPressEvent(nsIPresContext* aPresContext,
|
1998-11-24 07:46:58 +00:00
|
|
|
nsKeyEvent *aEvent,
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStatus* aStatus)
|
1998-11-24 07:46:58 +00:00
|
|
|
{
|
1999-04-27 22:14:17 +00:00
|
|
|
nsresult ret = NS_OK;
|
1998-11-24 07:46:58 +00:00
|
|
|
|
|
|
|
//fire keypress
|
|
|
|
nsKeyEvent event;
|
|
|
|
event.eventStructType = NS_KEY_EVENT;
|
|
|
|
event.message = NS_KEY_PRESS;
|
|
|
|
event.widget = nsnull;
|
|
|
|
event.keyCode = aEvent->keyCode;
|
|
|
|
|
|
|
|
nsIContent *content;
|
1999-02-10 00:42:56 +00:00
|
|
|
mCurrentTarget->GetContent(&content);
|
1998-11-24 07:46:58 +00:00
|
|
|
|
|
|
|
if (nsnull != content) {
|
1999-03-28 22:22:54 +00:00
|
|
|
ret = content->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, aStatus);
|
1998-11-24 07:46:58 +00:00
|
|
|
NS_RELEASE(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Now dispatch to the frame
|
|
|
|
if (nsnull != mCurrentTarget) {
|
|
|
|
mCurrentTarget->HandleEvent(aPresContext, &event, aStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
PRBool
|
1999-11-13 05:16:33 +00:00
|
|
|
nsEventStateManager::ChangeFocus(nsIContent* aFocusContent, nsIFrame* aFocusFrame, PRBool aSetFocus)
|
1999-03-02 19:19:24 +00:00
|
|
|
{
|
1999-11-13 05:16:33 +00:00
|
|
|
nsCOMPtr<nsIFocusableContent> focusChange = do_QueryInterface(aFocusContent);
|
1999-08-24 00:42:38 +00:00
|
|
|
|
1999-11-15 20:09:37 +00:00
|
|
|
if (focusChange && aFocusFrame) {
|
1999-11-13 05:16:33 +00:00
|
|
|
|
|
|
|
PRBool surpressBlurAndFocus = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIStyleContext> context;
|
|
|
|
aFocusFrame->GetStyleContext(getter_AddRefs(context));
|
|
|
|
|
|
|
|
const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface);
|
|
|
|
if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) {
|
|
|
|
// we want to surpress the blur and the following focus
|
|
|
|
surpressBlurAndFocus = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!surpressBlurAndFocus) {
|
1999-03-02 19:19:24 +00:00
|
|
|
if (aSetFocus) {
|
1999-11-13 05:16:33 +00:00
|
|
|
|
1999-11-23 07:05:53 +00:00
|
|
|
mLastFocusedContent = nsnull;
|
1999-03-02 19:19:24 +00:00
|
|
|
focusChange->SetFocus(mPresContext);
|
1999-11-23 07:05:53 +00:00
|
|
|
mLastFocusedContent = aFocusContent;
|
1999-11-13 05:16:33 +00:00
|
|
|
|
|
|
|
|
1999-11-23 07:05:53 +00:00
|
|
|
} else {
|
1999-03-02 19:19:24 +00:00
|
|
|
focusChange->RemoveFocus(mPresContext);
|
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
//XXX Need to deal with Object tag
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
void
|
1999-03-02 19:19:24 +00:00
|
|
|
nsEventStateManager::ShiftFocus(PRBool forward)
|
1998-11-18 05:25:26 +00:00
|
|
|
{
|
1999-04-12 21:24:07 +00:00
|
|
|
PRBool topOfDoc = PR_FALSE;
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
if (nsnull == mPresContext) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull == mCurrentFocus) {
|
|
|
|
if (nsnull == mDocument) {
|
1999-02-12 17:45:58 +00:00
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
mPresContext->GetShell(getter_AddRefs(presShell));
|
1999-02-12 18:41:26 +00:00
|
|
|
if (presShell) {
|
1999-02-12 17:45:58 +00:00
|
|
|
presShell->GetDocument(&mDocument);
|
1998-11-18 05:25:26 +00:00
|
|
|
if (nsnull == mDocument) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mCurrentFocus = mDocument->GetRootContent();
|
|
|
|
if (nsnull == mCurrentFocus) {
|
|
|
|
return;
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
mCurrentTabIndex = forward ? 1 : 0;
|
1999-04-12 21:24:07 +00:00
|
|
|
topOfDoc = PR_TRUE;
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
nsIContent* next = GetNextTabbableContent(mCurrentFocus, nsnull, mCurrentFocus, forward);
|
1998-11-18 05:25:26 +00:00
|
|
|
|
|
|
|
if (nsnull == next) {
|
1999-04-12 21:24:07 +00:00
|
|
|
PRBool focusTaken = PR_FALSE;
|
|
|
|
|
1999-07-19 21:23:57 +00:00
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
1999-03-02 19:19:24 +00:00
|
|
|
|
|
|
|
//Pass focus up to nsIWebShellContainer FocusAvailable
|
|
|
|
nsISupports* container;
|
|
|
|
mPresContext->GetContainer(&container);
|
|
|
|
if (nsnull != container) {
|
|
|
|
nsIWebShell* webShell;
|
|
|
|
if (NS_OK == container->QueryInterface(kIWebShellIID, (void**)&webShell)) {
|
|
|
|
nsIWebShellContainer* webShellContainer;
|
|
|
|
webShell->GetContainer(webShellContainer);
|
|
|
|
if (nsnull != webShellContainer) {
|
1999-04-12 21:24:07 +00:00
|
|
|
webShellContainer->FocusAvailable(webShell, focusTaken);
|
1999-03-02 19:19:24 +00:00
|
|
|
NS_RELEASE(webShellContainer);
|
|
|
|
}
|
|
|
|
NS_RELEASE(webShell);
|
|
|
|
}
|
|
|
|
NS_RELEASE(container);
|
|
|
|
}
|
1999-04-12 21:24:07 +00:00
|
|
|
if (!focusTaken && !topOfDoc) {
|
|
|
|
ShiftFocus(forward);
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1999-11-13 05:16:33 +00:00
|
|
|
ChangeFocus(next, mCurrentTarget, PR_TRUE);
|
1998-11-18 05:25:26 +00:00
|
|
|
|
|
|
|
NS_IF_RELEASE(mCurrentFocus);
|
|
|
|
mCurrentFocus = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* At some point this will need to be linked into HTML 4.0 tabindex
|
|
|
|
*/
|
|
|
|
nsIContent*
|
1999-03-02 19:19:24 +00:00
|
|
|
nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop, PRBool forward)
|
1998-11-18 05:25:26 +00:00
|
|
|
{
|
|
|
|
PRInt32 count, index;
|
|
|
|
aParent->ChildCount(count);
|
|
|
|
|
|
|
|
if (nsnull != aChild) {
|
|
|
|
aParent->IndexOf(aChild, index);
|
1999-03-02 19:19:24 +00:00
|
|
|
index += forward ? 1 : -1;
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-07-19 21:23:57 +00:00
|
|
|
index = forward ? 0 : count-1;
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
for (;index < count && index >= 0;index += forward ? 1 : -1) {
|
1998-11-18 05:25:26 +00:00
|
|
|
nsIContent* child;
|
1999-03-02 19:19:24 +00:00
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
aParent->ChildAt(index, child);
|
1999-03-02 19:19:24 +00:00
|
|
|
nsIContent* content = GetNextTabbableContent(child, nsnull, aTop, forward);
|
1998-11-18 05:25:26 +00:00
|
|
|
if (content != nsnull) {
|
|
|
|
NS_IF_RELEASE(child);
|
|
|
|
return content;
|
|
|
|
}
|
|
|
|
if (nsnull != child) {
|
|
|
|
nsIAtom* tag;
|
1999-03-02 19:19:24 +00:00
|
|
|
PRInt32 tabIndex = -1;
|
1998-11-18 05:25:26 +00:00
|
|
|
PRBool disabled = PR_TRUE;
|
1999-01-28 23:14:36 +00:00
|
|
|
PRBool hidden = PR_FALSE;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
|
|
|
child->GetTag(tag);
|
|
|
|
if (nsHTMLAtoms::input==tag) {
|
|
|
|
nsIDOMHTMLInputElement *nextInput;
|
|
|
|
if (NS_OK == child->QueryInterface(kIDOMHTMLInputElementIID,(void **)&nextInput)) {
|
|
|
|
nextInput->GetDisabled(&disabled);
|
1999-03-02 19:19:24 +00:00
|
|
|
nextInput->GetTabIndex(&tabIndex);
|
1999-01-28 23:14:36 +00:00
|
|
|
|
|
|
|
nsAutoString type;
|
|
|
|
nextInput->GetType(type);
|
|
|
|
if (type.EqualsIgnoreCase("hidden")) {
|
|
|
|
hidden = PR_TRUE;
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_RELEASE(nextInput);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::select==tag) {
|
|
|
|
nsIDOMHTMLSelectElement *nextSelect;
|
|
|
|
if (NS_OK == child->QueryInterface(kIDOMHTMLSelectElementIID,(void **)&nextSelect)) {
|
|
|
|
nextSelect->GetDisabled(&disabled);
|
1999-03-02 19:19:24 +00:00
|
|
|
nextSelect->GetTabIndex(&tabIndex);
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_RELEASE(nextSelect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::textarea==tag) {
|
|
|
|
nsIDOMHTMLTextAreaElement *nextTextArea;
|
|
|
|
if (NS_OK == child->QueryInterface(kIDOMHTMLTextAreaElementIID,(void **)&nextTextArea)) {
|
|
|
|
nextTextArea->GetDisabled(&disabled);
|
1999-03-02 19:19:24 +00:00
|
|
|
nextTextArea->GetTabIndex(&tabIndex);
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_RELEASE(nextTextArea);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
else if(nsHTMLAtoms::a==tag) {
|
|
|
|
nsIDOMHTMLAnchorElement *nextAnchor;
|
|
|
|
if (NS_OK == child->QueryInterface(kIDOMHTMLAnchorElementIID,(void **)&nextAnchor)) {
|
|
|
|
nextAnchor->GetTabIndex(&tabIndex);
|
|
|
|
NS_RELEASE(nextAnchor);
|
|
|
|
}
|
|
|
|
disabled = PR_FALSE;
|
|
|
|
}
|
|
|
|
else if(nsHTMLAtoms::button==tag) {
|
|
|
|
nsIDOMHTMLButtonElement *nextButton;
|
|
|
|
if (NS_OK == child->QueryInterface(kIDOMHTMLButtonElementIID,(void **)&nextButton)) {
|
|
|
|
nextButton->GetTabIndex(&tabIndex);
|
|
|
|
nextButton->GetDisabled(&disabled);
|
|
|
|
NS_RELEASE(nextButton);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nsHTMLAtoms::area==tag) {
|
|
|
|
nsIDOMHTMLAreaElement *nextArea;
|
|
|
|
if (NS_OK == child->QueryInterface(kIDOMHTMLAreaElementIID,(void **)&nextArea)) {
|
|
|
|
nextArea->GetTabIndex(&tabIndex);
|
|
|
|
NS_RELEASE(nextArea);
|
|
|
|
}
|
|
|
|
disabled = PR_FALSE;
|
|
|
|
}
|
|
|
|
else if(nsHTMLAtoms::object==tag) {
|
|
|
|
nsIDOMHTMLObjectElement *nextObject;
|
|
|
|
if (NS_OK == child->QueryInterface(kIDOMHTMLObjectElementIID,(void **)&nextObject)) {
|
|
|
|
nextObject->GetTabIndex(&tabIndex);
|
|
|
|
NS_RELEASE(nextObject);
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
disabled = PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
//TabIndex not set (-1) treated at same level as set to 0
|
|
|
|
tabIndex = tabIndex < 0 ? 0 : tabIndex;
|
|
|
|
|
|
|
|
if (!disabled && !hidden && mCurrentTabIndex == tabIndex) {
|
1998-11-18 05:25:26 +00:00
|
|
|
return child;
|
|
|
|
}
|
|
|
|
NS_RELEASE(child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aParent == aTop) {
|
|
|
|
nsIContent* nextParent;
|
|
|
|
aParent->GetParent(nextParent);
|
|
|
|
if (nsnull != nextParent) {
|
1999-03-02 19:19:24 +00:00
|
|
|
nsIContent* content = GetNextTabbableContent(nextParent, aParent, nextParent, forward);
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_RELEASE(nextParent);
|
|
|
|
return content;
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
//Reached end of document
|
|
|
|
else {
|
|
|
|
//If already at lowest priority tab (0), end
|
1999-07-19 21:23:57 +00:00
|
|
|
if (((forward) && (0 == mCurrentTabIndex)) ||
|
|
|
|
((!forward) && (1 == mCurrentTabIndex))) {
|
1999-03-02 19:19:24 +00:00
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
//else continue looking for next highest priority tab
|
|
|
|
mCurrentTabIndex = GetNextTabIndex(aParent, forward);
|
|
|
|
nsIContent* content = GetNextTabbableContent(aParent, nsnull, aParent, forward);
|
|
|
|
return content;
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
PRInt32
|
|
|
|
nsEventStateManager::GetNextTabIndex(nsIContent* aParent, PRBool forward)
|
|
|
|
{
|
1999-07-19 21:23:57 +00:00
|
|
|
PRInt32 count, tabIndex, childTabIndex;
|
|
|
|
nsIContent* child;
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
aParent->ChildCount(count);
|
1999-07-19 21:23:57 +00:00
|
|
|
|
|
|
|
if (forward) {
|
|
|
|
tabIndex = 0;
|
|
|
|
for (PRInt32 index = 0; index < count; index++) {
|
|
|
|
aParent->ChildAt(index, child);
|
|
|
|
childTabIndex = GetNextTabIndex(child, forward);
|
|
|
|
if (childTabIndex > mCurrentTabIndex && childTabIndex != tabIndex) {
|
|
|
|
tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString tabIndexStr;
|
|
|
|
child->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndexStr);
|
|
|
|
PRInt32 ec, val = tabIndexStr.ToInteger(&ec);
|
|
|
|
if (NS_OK == ec && val > mCurrentTabIndex && val != tabIndex) {
|
|
|
|
tabIndex = (tabIndex == 0 || val < tabIndex) ? val : tabIndex;
|
|
|
|
}
|
|
|
|
NS_RELEASE(child);
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
1999-07-19 21:23:57 +00:00
|
|
|
}
|
|
|
|
else { /* !forward */
|
|
|
|
tabIndex = 1;
|
|
|
|
for (PRInt32 index = 0; index < count; index++) {
|
|
|
|
aParent->ChildAt(index, child);
|
|
|
|
childTabIndex = GetNextTabIndex(child, forward);
|
|
|
|
if ((mCurrentTabIndex==0 && childTabIndex > tabIndex) ||
|
|
|
|
(childTabIndex < mCurrentTabIndex && childTabIndex > tabIndex)) {
|
|
|
|
tabIndex = childTabIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString tabIndexStr;
|
|
|
|
child->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndexStr);
|
|
|
|
PRInt32 ec, val = tabIndexStr.ToInteger(&ec);
|
|
|
|
if (NS_OK == ec) {
|
|
|
|
if ((mCurrentTabIndex==0 && val > tabIndex) ||
|
|
|
|
(val < mCurrentTabIndex && val > tabIndex) ) {
|
|
|
|
tabIndex = val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(child);
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return tabIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::GetEventTarget(nsIFrame **aFrame)
|
|
|
|
{
|
1999-06-15 03:14:28 +00:00
|
|
|
if (!mCurrentTarget && mCurrentTargetContent) {
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
if (mPresContext) {
|
|
|
|
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
if (NS_SUCCEEDED(rv) && shell){
|
|
|
|
shell->GetPrimaryFrameFor(mCurrentTargetContent, &mCurrentTarget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
*aFrame = mCurrentTarget;
|
1999-07-27 20:55:03 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::GetEventTargetContent(nsIContent** aContent)
|
|
|
|
{
|
|
|
|
if (mCurrentTargetContent) {
|
|
|
|
*aContent = mCurrentTargetContent;
|
|
|
|
NS_IF_ADDREF(*aContent);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mCurrentTarget) {
|
|
|
|
mCurrentTarget->GetContent(aContent);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-06-15 03:14:28 +00:00
|
|
|
|
1999-07-27 20:55:03 +00:00
|
|
|
*aContent = nsnull;
|
1998-06-23 21:53:02 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-03 07:11:45 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::GetEventRelatedContent(nsIContent** aContent)
|
|
|
|
{
|
|
|
|
if (mCurrentRelatedContent) {
|
|
|
|
*aContent = mCurrentRelatedContent;
|
|
|
|
NS_IF_ADDREF(*aContent);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aContent = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_IMETHODIMP
|
1999-03-28 22:22:54 +00:00
|
|
|
nsEventStateManager::GetContentState(nsIContent *aContent, PRInt32& aState)
|
1998-08-07 04:45:03 +00:00
|
|
|
{
|
1999-03-28 22:22:54 +00:00
|
|
|
aState = NS_EVENT_STATE_UNSPECIFIED;
|
|
|
|
|
|
|
|
if (aContent == mActiveContent) {
|
|
|
|
aState |= NS_EVENT_STATE_ACTIVE;
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
1999-03-28 22:22:54 +00:00
|
|
|
if (aContent == mHoverContent) {
|
|
|
|
aState |= NS_EVENT_STATE_HOVER;
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
1999-03-28 22:22:54 +00:00
|
|
|
if (aContent == mCurrentFocus) {
|
|
|
|
aState |= NS_EVENT_STATE_FOCUS;
|
1998-08-07 04:45:03 +00:00
|
|
|
}
|
1999-05-04 14:44:51 +00:00
|
|
|
if (aContent == mDragOverContent) {
|
|
|
|
aState |= NS_EVENT_STATE_DRAGOVER;
|
|
|
|
}
|
1998-08-07 04:45:03 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_IMETHODIMP
|
1999-04-12 21:24:07 +00:00
|
|
|
nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState)
|
1998-08-07 04:45:03 +00:00
|
|
|
{
|
1999-05-04 14:44:51 +00:00
|
|
|
const PRInt32 maxNotify = 5;
|
|
|
|
nsIContent *notifyContent[maxNotify] = {nsnull, nsnull, nsnull, nsnull, nsnull};
|
|
|
|
|
|
|
|
if ((aState & NS_EVENT_STATE_DRAGOVER) && (aContent != mDragOverContent)) {
|
|
|
|
//transferring ref to notifyContent from mDragOverContent
|
|
|
|
notifyContent[4] = mDragOverContent; // notify dragover first, since more common case
|
|
|
|
mDragOverContent = aContent;
|
|
|
|
NS_IF_ADDREF(mDragOverContent);
|
|
|
|
}
|
1999-04-20 00:03:30 +00:00
|
|
|
|
|
|
|
if ((aState & NS_EVENT_STATE_ACTIVE) && (aContent != mActiveContent)) {
|
|
|
|
//transferring ref to notifyContent from mActiveContent
|
|
|
|
notifyContent[2] = mActiveContent;
|
|
|
|
mActiveContent = aContent;
|
|
|
|
NS_IF_ADDREF(mActiveContent);
|
|
|
|
}
|
1999-03-28 22:22:54 +00:00
|
|
|
|
1999-04-20 00:03:30 +00:00
|
|
|
if ((aState & NS_EVENT_STATE_HOVER) && (aContent != mHoverContent)) {
|
|
|
|
//transferring ref to notifyContent from mHoverContent
|
|
|
|
notifyContent[1] = mHoverContent; // notify hover first, since more common case
|
|
|
|
mHoverContent = aContent;
|
|
|
|
NS_IF_ADDREF(mHoverContent);
|
1998-08-07 04:45:03 +00:00
|
|
|
}
|
|
|
|
|
1999-04-20 00:03:30 +00:00
|
|
|
if ((aState & NS_EVENT_STATE_FOCUS) && (aContent != mCurrentFocus)) {
|
1999-10-26 04:44:41 +00:00
|
|
|
SendFocusBlur(mPresContext, aContent);
|
1999-01-28 23:14:36 +00:00
|
|
|
|
1999-04-20 00:03:30 +00:00
|
|
|
//transferring ref to notifyContent from mCurrentFocus
|
|
|
|
notifyContent[3] = mCurrentFocus;
|
|
|
|
mCurrentFocus = aContent;
|
|
|
|
NS_IF_ADDREF(mCurrentFocus);
|
1998-08-07 04:45:03 +00:00
|
|
|
}
|
1999-01-28 23:14:36 +00:00
|
|
|
|
1999-04-20 00:03:30 +00:00
|
|
|
if (aContent) { // notify about new content too
|
|
|
|
notifyContent[0] = aContent;
|
|
|
|
NS_ADDREF(aContent); // everything in notify array has a ref
|
|
|
|
}
|
1999-01-28 23:14:36 +00:00
|
|
|
|
1999-05-04 14:44:51 +00:00
|
|
|
// remove duplicates
|
|
|
|
if ((notifyContent[4] == notifyContent[3]) || (notifyContent[4] == notifyContent[2]) || (notifyContent[4] == notifyContent[1])) {
|
1999-06-08 19:01:56 +00:00
|
|
|
NS_IF_RELEASE(notifyContent[4]);
|
1999-05-04 14:44:51 +00:00
|
|
|
}
|
1999-04-20 00:03:30 +00:00
|
|
|
// remove duplicates
|
|
|
|
if ((notifyContent[3] == notifyContent[2]) || (notifyContent[3] == notifyContent[1])) {
|
1999-06-08 19:01:56 +00:00
|
|
|
NS_IF_RELEASE(notifyContent[3]);
|
1999-04-20 00:03:30 +00:00
|
|
|
}
|
|
|
|
if (notifyContent[2] == notifyContent[1]) {
|
1999-06-08 19:01:56 +00:00
|
|
|
NS_IF_RELEASE(notifyContent[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove notifications for content not in document.
|
|
|
|
// we may decide this is possible later but right now it has problems.
|
|
|
|
nsIDocument* doc = nsnull;
|
|
|
|
for (int i = 0; i < maxNotify; i++) {
|
|
|
|
if (notifyContent[i] && NS_SUCCEEDED(notifyContent[i]->GetDocument(doc)) && !doc) {
|
|
|
|
NS_RELEASE(notifyContent[i]);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(doc);
|
1999-04-20 00:03:30 +00:00
|
|
|
}
|
1999-03-28 22:22:54 +00:00
|
|
|
|
1999-04-20 00:03:30 +00:00
|
|
|
// compress the notify array to group notifications tighter
|
|
|
|
nsIContent** from = &(notifyContent[0]);
|
|
|
|
nsIContent** to = &(notifyContent[0]);
|
|
|
|
nsIContent** end = &(notifyContent[maxNotify]);
|
|
|
|
|
|
|
|
while (from < end) {
|
|
|
|
if (! *from) {
|
|
|
|
while (++from < end) {
|
|
|
|
if (*from) {
|
|
|
|
*to++ = *from;
|
|
|
|
*from = nsnull;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (from == to) {
|
|
|
|
to++;
|
|
|
|
from++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*to++ = *from;
|
|
|
|
*from++ = nsnull;
|
1999-04-12 21:24:07 +00:00
|
|
|
}
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-04-20 00:03:30 +00:00
|
|
|
if (notifyContent[0]) { // have at least one to notify about
|
|
|
|
nsIDocument *document; // this presumes content can't get/lose state if not connected to doc
|
|
|
|
notifyContent[0]->GetDocument(document);
|
1999-04-12 21:24:07 +00:00
|
|
|
if (document) {
|
1999-04-20 00:03:30 +00:00
|
|
|
document->ContentStatesChanged(notifyContent[0], notifyContent[1]);
|
|
|
|
if (notifyContent[2]) { // more that two notifications are needed (should be rare)
|
|
|
|
// XXX a further optimization here would be to group the notification pairs
|
|
|
|
// together by parent/child, only needed if more than two content changed
|
|
|
|
// (ie: if [0] and [2] are parent/child, then notify (0,2) (1,3))
|
|
|
|
document->ContentStatesChanged(notifyContent[2], notifyContent[3]);
|
1999-05-04 14:44:51 +00:00
|
|
|
if (notifyContent[4]) { // more that two notifications are needed (should be rare)
|
|
|
|
document->ContentStatesChanged(notifyContent[4], nsnull);
|
|
|
|
}
|
1999-04-20 00:03:30 +00:00
|
|
|
}
|
1999-04-12 21:24:07 +00:00
|
|
|
NS_RELEASE(document);
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
1999-04-20 00:03:30 +00:00
|
|
|
|
|
|
|
from = &(notifyContent[0]);
|
|
|
|
while (from < to) { // release old refs now that we are through
|
|
|
|
nsIContent* notify = *from++;
|
|
|
|
NS_RELEASE(notify);
|
|
|
|
}
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
|
|
|
|
1998-08-07 04:45:03 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-26 04:44:41 +00:00
|
|
|
nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aContent)
|
1999-03-02 19:19:24 +00:00
|
|
|
{
|
|
|
|
if (mCurrentFocus == aContent) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-13 05:16:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
PRBool surpressBlurAndFocus = PR_FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(mCurrentTarget) {
|
|
|
|
nsCOMPtr<nsIStyleContext> context;
|
|
|
|
mCurrentTarget->GetStyleContext(getter_AddRefs(context));
|
|
|
|
if(!context) return NS_OK;
|
|
|
|
|
|
|
|
|
|
|
|
const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface);
|
|
|
|
if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) {
|
|
|
|
// we want to surpress the blur and the following focus
|
|
|
|
surpressBlurAndFocus = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!surpressBlurAndFocus) {
|
|
|
|
|
1999-08-07 23:18:35 +00:00
|
|
|
nsIContent* targetBeforeEvent = mCurrentTargetContent;
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
if (mCurrentFocus) {
|
1999-10-13 04:19:26 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
|
|
|
|
// Make sure the content still has a document reference. If not,
|
|
|
|
// then we assume it is no longer in the content tree and should
|
|
|
|
// not receive the event.
|
|
|
|
nsresult result = mCurrentFocus->GetDocument(*getter_AddRefs(doc));
|
|
|
|
if (NS_SUCCEEDED(result) && doc) {
|
1999-11-13 05:16:33 +00:00
|
|
|
ChangeFocus(mCurrentFocus, mCurrentTarget, PR_FALSE);
|
1999-10-13 04:19:26 +00:00
|
|
|
|
|
|
|
//fire blur
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
|
|
|
|
|
|
|
mCurrentTargetContent = mCurrentFocus;
|
|
|
|
NS_ADDREF(mCurrentTargetContent);
|
|
|
|
|
|
|
|
if (nsnull != mPresContext) {
|
1999-11-24 06:03:41 +00:00
|
|
|
mCurrentFocus->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-10-13 04:19:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-04-12 21:24:07 +00:00
|
|
|
if (nsnull != aContent) {
|
|
|
|
//fire focus
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_FOCUS_CONTENT;
|
1999-03-02 19:19:24 +00:00
|
|
|
|
1999-08-07 23:18:35 +00:00
|
|
|
mCurrentTargetContent = aContent;
|
|
|
|
NS_ADDREF(mCurrentTargetContent);
|
|
|
|
|
1999-04-12 21:24:07 +00:00
|
|
|
if (nsnull != mPresContext) {
|
1999-11-24 06:03:41 +00:00
|
|
|
aContent->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-04-12 21:24:07 +00:00
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
|
1999-09-21 19:00:55 +00:00
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
1999-08-07 23:18:35 +00:00
|
|
|
|
|
|
|
//reset mCurretTargetContent to what it was
|
|
|
|
mCurrentTargetContent = targetBeforeEvent;
|
|
|
|
|
1999-04-12 21:24:07 +00:00
|
|
|
nsAutoString tabIndex;
|
|
|
|
aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndex);
|
|
|
|
PRInt32 ec, val = tabIndex.ToInteger(&ec);
|
|
|
|
if (NS_OK == ec) {
|
|
|
|
mCurrentTabIndex = val;
|
|
|
|
}
|
1999-09-20 22:18:57 +00:00
|
|
|
|
1999-10-19 21:57:43 +00:00
|
|
|
nsIFrame * currentFocusFrame = nsnull;
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
if (mPresContext) {
|
|
|
|
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
if (NS_SUCCEEDED(rv) && shell){
|
|
|
|
shell->GetPrimaryFrameFor(aContent, ¤tFocusFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if the newly focused content's frame has a view with a widget
|
1999-09-20 22:18:57 +00:00
|
|
|
// i.e TextField or TextArea, if so, don't set the focus on their window
|
|
|
|
PRBool shouldSetFocusOnWindow = PR_TRUE;
|
1999-10-19 21:57:43 +00:00
|
|
|
if (nsnull != currentFocusFrame) {
|
1999-09-20 22:18:57 +00:00
|
|
|
nsIView * view = nsnull;
|
1999-10-26 04:44:41 +00:00
|
|
|
currentFocusFrame->GetView(aPresContext, &view);
|
1999-09-20 22:18:57 +00:00
|
|
|
if (view != nsnull) {
|
|
|
|
nsIWidget *window = nsnull;
|
|
|
|
view->GetWidget(window);
|
|
|
|
if (window != nsnull) { // addrefs
|
|
|
|
shouldSetFocusOnWindow = PR_FALSE;
|
|
|
|
NS_RELEASE(window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the window that this frame is in and
|
|
|
|
// make sure it has focus
|
|
|
|
// XXX Note: mLastWindowToHaveFocus this does not track when ANY focus
|
|
|
|
// event comes through, the only place this gets set is here
|
|
|
|
// so some windows may get multiple focus events
|
|
|
|
// For example, if you clicked in the window (generates focus event)
|
|
|
|
// then click on a gfx control (generates another focus event)
|
1999-10-19 21:57:43 +00:00
|
|
|
if (shouldSetFocusOnWindow && nsnull != currentFocusFrame) {
|
1999-09-20 22:18:57 +00:00
|
|
|
nsIFrame * parentFrame;
|
1999-10-26 04:44:41 +00:00
|
|
|
currentFocusFrame->GetParentWithView(aPresContext, &parentFrame);
|
1999-09-20 22:18:57 +00:00
|
|
|
if (nsnull != parentFrame) {
|
|
|
|
nsIView * pView;
|
1999-10-26 04:44:41 +00:00
|
|
|
parentFrame->GetView(aPresContext, &pView);
|
1999-09-20 22:18:57 +00:00
|
|
|
if (nsnull != pView) {
|
|
|
|
nsIWidget *window = nsnull;
|
|
|
|
|
|
|
|
nsIView *ancestor = pView;
|
|
|
|
while (nsnull != ancestor) {
|
|
|
|
ancestor->GetWidget(window); // addrefs
|
|
|
|
if (nsnull != window) {
|
|
|
|
if (window != mLastWindowToHaveFocus) {
|
|
|
|
window->SetFocus();
|
|
|
|
NS_IF_RELEASE(mLastWindowToHaveFocus);
|
|
|
|
mLastWindowToHaveFocus = window;
|
|
|
|
} else {
|
|
|
|
NS_IF_RELEASE(window);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ancestor->GetParent(ancestor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
|
|
|
|
1999-11-13 05:16:33 +00:00
|
|
|
}
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-07-26 15:02:19 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::GetFocusedContent(nsIContent** aContent)
|
|
|
|
{
|
|
|
|
*aContent = mCurrentFocus;
|
|
|
|
NS_IF_ADDREF(*aContent);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-21 01:46:41 +00:00
|
|
|
nsIFrame*
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::GetDocumentFrame(nsIPresContext* aPresContext)
|
1999-11-21 01:46:41 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
nsIDocument* aDocument;
|
|
|
|
nsIFrame* aFrame;
|
|
|
|
nsIView* aView;
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
1999-11-21 01:46:41 +00:00
|
|
|
if (nsnull == presShell) {
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("Got a null PresShell\n");
|
|
|
|
#endif
|
|
|
|
return nsnull; // someone will have to tell me wtf this means
|
|
|
|
}
|
|
|
|
presShell->GetDocument(&aDocument);
|
|
|
|
presShell->GetPrimaryFrameFor(aDocument->GetRootContent(), &aFrame);
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrame->GetView(aPresContext, &aView);
|
1999-11-21 01:46:41 +00:00
|
|
|
if (!aView) {
|
|
|
|
#ifdef DEBUG_scroll
|
|
|
|
printf("looking for a parent with a view\n");
|
|
|
|
#endif
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrame->GetParentWithView(aPresContext, &aFrame);
|
1999-11-21 01:46:41 +00:00
|
|
|
}
|
|
|
|
return aFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-06-23 21:53:02 +00:00
|
|
|
nsresult NS_NewEventStateManager(nsIEventStateManager** aInstancePtrResult)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aInstancePtrResult, "nsnull ptr");
|
|
|
|
if (nsnull == aInstancePtrResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
nsIEventStateManager* manager = new nsEventStateManager();
|
|
|
|
if (nsnull == manager) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
1999-11-23 07:05:53 +00:00
|
|
|
return manager->QueryInterface(NS_GET_IID(nsIEventStateManager), (void **) aInstancePtrResult);
|
1998-06-23 21:53:02 +00:00
|
|
|
}
|
|
|
|
|