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
|
|
|
*/
|
2000-03-16 03:34:52 +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"
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
#include "nsIDOMHTMLImageElement.h"
|
|
|
|
#include "nsIDOMHTMLMapElement.h"
|
2001-05-22 23:52:17 +00:00
|
|
|
#include "nsIDOMHTMLBodyElement.h"
|
2001-04-18 00:14:34 +00:00
|
|
|
#include "nsImageMapUtils.h"
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
#include "nsIHTMLDocument.h"
|
1999-03-02 19:19:24 +00:00
|
|
|
#include "nsINameSpaceManager.h" // for kNameSpaceID_HTML
|
|
|
|
#include "nsIWebShell.h"
|
2000-02-11 01:56:01 +00:00
|
|
|
#include "nsIBaseWindow.h"
|
1999-04-30 19:38:39 +00:00
|
|
|
#include "nsIScrollableView.h"
|
2000-09-14 11:45:01 +00:00
|
|
|
#include "nsISelection.h"
|
1999-05-07 21:12:59 +00:00
|
|
|
#include "nsIFrameSelection.h"
|
1999-08-19 19:48:45 +00:00
|
|
|
#include "nsIDeviceContext.h"
|
1999-11-13 05:16:33 +00:00
|
|
|
#include "nsIScriptGlobalObject.h"
|
1999-12-08 04:54:29 +00:00
|
|
|
#include "nsIPrivateDOMEvent.h"
|
2000-09-01 01:54:35 +00:00
|
|
|
#include "nsIDOMWindowInternal.h"
|
1999-12-18 04:02:28 +00:00
|
|
|
#include "nsPIDOMWindow.h"
|
2000-04-04 23:55:31 +00:00
|
|
|
#include "nsIEnumerator.h"
|
|
|
|
#include "nsFrameTraversal.h"
|
2000-04-16 06:14:38 +00:00
|
|
|
#include "nsIDocShellTreeItem.h"
|
|
|
|
#include "nsIWebNavigation.h"
|
1999-08-19 19:48:45 +00:00
|
|
|
|
2000-01-06 06:22:00 +00:00
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsIPref.h"
|
|
|
|
|
2000-11-04 08:21:20 +00:00
|
|
|
#include "nsIChromeEventHandler.h"
|
|
|
|
#include "nsIFocusController.h"
|
|
|
|
|
2000-01-13 11:43:54 +00:00
|
|
|
#include "nsXULAtoms.h"
|
2000-02-11 23:41:13 +00:00
|
|
|
#include "nsIDOMXULDocument.h"
|
2000-03-15 04:03:44 +00:00
|
|
|
#include "nsIObserverService.h"
|
2000-05-15 02:10:11 +00:00
|
|
|
#include "nsIDocShell.h"
|
|
|
|
#include "nsIMarkupDocumentViewer.h"
|
2000-06-28 20:35:32 +00:00
|
|
|
#include "nsITreeFrame.h"
|
2001-03-06 22:16:42 +00:00
|
|
|
#include "nsIOutlinerBoxObject.h"
|
2000-12-09 07:28:19 +00:00
|
|
|
#include "nsIScrollableViewProvider.h"
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
#include "nsIDOMDocumentRange.h"
|
2001-02-15 05:07:46 +00:00
|
|
|
|
|
|
|
#include "nsIDOMRange.h"
|
|
|
|
#include "nsICaret.h"
|
|
|
|
#include "nsILookAndFeel.h"
|
|
|
|
#include "nsWidgetsCID.h"
|
|
|
|
#include "nsIFormControl.h"
|
2000-01-13 11:43:54 +00:00
|
|
|
|
2001-02-19 12:55:42 +00:00
|
|
|
#include "nsIFrameTraversal.h"
|
|
|
|
#include "nsLayoutCID.h"
|
2001-03-30 04:45:40 +00:00
|
|
|
#include "nsHTMLAtoms.h"
|
|
|
|
#include "nsXULAtoms.h"
|
|
|
|
#include "nsIDOMHTMLFormElement.h"
|
2001-05-22 23:52:17 +00:00
|
|
|
#include "nsIDOMHTMLFrameSetElement.h"
|
|
|
|
#include "nsIDOMHTMLFrameElement.h"
|
|
|
|
#include "nsIDOMHTMLIFrameElement.h"
|
|
|
|
#include "nsIDocShellTreeItem.h"
|
|
|
|
#include "nsIDocShellTreeNode.h"
|
|
|
|
|
|
|
|
#ifdef DEBUG_rods
|
|
|
|
//#define DEBUG_DOCSHELL_FOCUS
|
|
|
|
#endif
|
2001-03-30 04:45:40 +00:00
|
|
|
|
2001-05-22 23:52:17 +00:00
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
static char* gDocTypeNames[] = {"eChrome", "eGenericContent", "eFrameSet", "eFrame", "eIFrame"};
|
|
|
|
#endif
|
2001-04-12 23:39:19 +00:00
|
|
|
|
2001-02-19 12:55:42 +00:00
|
|
|
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
|
|
|
|
|
2001-03-30 04:45:40 +00:00
|
|
|
|
1999-12-11 00:02:08 +00:00
|
|
|
//we will use key binding by default now. this wil lbreak viewer for now
|
2001-02-15 05:07:46 +00:00
|
|
|
#define NON_KEYBINDING 0
|
1999-12-11 00:02:08 +00:00
|
|
|
|
2000-03-15 04:03:44 +00:00
|
|
|
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
|
2001-02-15 05:07:46 +00:00
|
|
|
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
2000-03-15 04:03:44 +00:00
|
|
|
|
1999-12-08 20:18:16 +00:00
|
|
|
nsIContent * gLastFocusedContent = 0; // Strong reference
|
1999-12-01 09:09:46 +00:00
|
|
|
nsIDocument * gLastFocusedDocument = 0; // Strong reference
|
1999-12-08 20:18:16 +00:00
|
|
|
nsIPresContext* gLastFocusedPresContext = 0; // Weak reference
|
1999-12-01 09:09:46 +00:00
|
|
|
|
|
|
|
PRUint32 nsEventStateManager::mInstanceCount = 0;
|
|
|
|
|
2000-01-06 06:22:00 +00:00
|
|
|
enum {
|
|
|
|
MOUSE_SCROLL_N_LINES,
|
|
|
|
MOUSE_SCROLL_PAGE,
|
2000-04-25 06:25:43 +00:00
|
|
|
MOUSE_SCROLL_HISTORY,
|
|
|
|
MOUSE_SCROLL_TEXTSIZE
|
2000-01-06 06:22:00 +00:00
|
|
|
};
|
|
|
|
|
1999-08-19 19:48:45 +00:00
|
|
|
nsEventStateManager::nsEventStateManager()
|
2000-03-15 04:03:44 +00:00
|
|
|
: mGestureDownPoint(0,0),
|
|
|
|
m_haveShutdown(PR_FALSE)
|
1999-08-19 19:48:45 +00:00
|
|
|
{
|
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-12-18 04:02:28 +00:00
|
|
|
mConsumeFocusEvents = PR_FALSE;
|
2000-04-24 04:41:27 +00:00
|
|
|
mLockCursor = 0;
|
1999-12-18 04:02:28 +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;
|
2000-02-11 05:20:44 +00:00
|
|
|
mFirstBlurEvent = nsnull;
|
|
|
|
mFirstFocusEvent = nsnull;
|
2000-05-16 10:22:20 +00:00
|
|
|
mAccessKeys = nsnull;
|
2001-02-15 05:07:46 +00:00
|
|
|
mBrowseWithCaret = PR_FALSE;
|
2000-09-15 06:17:54 +00:00
|
|
|
hHover = PR_FALSE;
|
2001-05-22 23:52:17 +00:00
|
|
|
mSpecialTopOfDoc = PR_FALSE;
|
|
|
|
|
1998-06-25 14:51:48 +00:00
|
|
|
NS_INIT_REFCNT();
|
2001-03-30 04:45:40 +00:00
|
|
|
|
|
|
|
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
|
|
|
mEventDownWidget = nsnull;
|
|
|
|
#endif
|
1999-12-01 09:09:46 +00:00
|
|
|
|
|
|
|
++mInstanceCount;
|
2000-03-15 04:03:44 +00:00
|
|
|
}
|
|
|
|
|
2000-03-15 05:02:23 +00:00
|
|
|
NS_IMETHODIMP
|
2000-03-15 04:03:44 +00:00
|
|
|
nsEventStateManager::Init()
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIObserverService, observerService,
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_OBSERVERSERVICE_CONTRACTID, &rv);
|
2000-03-15 04:03:44 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
{
|
2000-04-03 11:20:35 +00:00
|
|
|
nsAutoString topic; topic.AssignWithConversion(NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
2000-03-15 04:03:44 +00:00
|
|
|
observerService->AddObserver(this, topic.GetUnicode());
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = getPrefService();
|
2000-09-15 06:17:54 +00:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mPrefService->GetBoolPref("nglayout.events.showHierarchicalHover", &hHover);
|
|
|
|
}
|
|
|
|
|
2000-03-15 04:03:44 +00:00
|
|
|
return rv;
|
1998-06-23 21:53:02 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 14:54:59 +00:00
|
|
|
nsEventStateManager::~nsEventStateManager()
|
|
|
|
{
|
2001-04-26 19:12:31 +00:00
|
|
|
#if CLICK_HOLD_CONTEXT_MENUS
|
|
|
|
if ( mClickHoldTimer ) {
|
|
|
|
mClickHoldTimer->Cancel();
|
|
|
|
mClickHoldTimer = nsnull;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
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);
|
2000-02-11 05:20:44 +00:00
|
|
|
NS_IF_RELEASE(mFirstBlurEvent);
|
|
|
|
NS_IF_RELEASE(mFirstFocusEvent);
|
1999-12-01 09:09:46 +00:00
|
|
|
|
|
|
|
--mInstanceCount;
|
|
|
|
if(mInstanceCount == 0) {
|
|
|
|
NS_IF_RELEASE(gLastFocusedContent);
|
|
|
|
NS_IF_RELEASE(gLastFocusedDocument);
|
|
|
|
}
|
2000-03-15 04:03:44 +00:00
|
|
|
|
2000-05-16 10:22:20 +00:00
|
|
|
if (mAccessKeys) {
|
|
|
|
delete mAccessKeys;
|
|
|
|
}
|
|
|
|
|
2000-03-15 04:03:44 +00:00
|
|
|
if (!m_haveShutdown) {
|
|
|
|
Shutdown();
|
|
|
|
|
|
|
|
// Don't remove from Observer service in Shutdown because Shutdown also
|
|
|
|
// gets called from xpcom shutdown observer. And we don't want to remove
|
|
|
|
// from the service in that case.
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
NS_WITH_SERVICE (nsIObserverService, observerService,
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_OBSERVERSERVICE_CONTRACTID, &rv);
|
2000-03-15 04:03:44 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
{
|
2000-04-03 11:20:35 +00:00
|
|
|
nsAutoString topic; topic.AssignWithConversion(NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
2000-03-15 04:03:44 +00:00
|
|
|
observerService->RemoveObserver(this, topic.GetUnicode());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-06-23 21:53:02 +00:00
|
|
|
}
|
|
|
|
|
2000-03-15 04:03:44 +00:00
|
|
|
nsresult
|
|
|
|
nsEventStateManager::Shutdown()
|
|
|
|
{
|
|
|
|
if (mPrefService) {
|
|
|
|
mPrefService = null_nsCOMPtr();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_haveShutdown = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsEventStateManager::getPrefService()
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (!mPrefService) {
|
|
|
|
mPrefService = do_GetService(kPrefCID, &rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (!mPrefService) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::Observe(nsISupports *aSubject, const PRUnichar *aTopic,
|
|
|
|
const PRUnichar *someData) {
|
|
|
|
nsAutoString topicString(aTopic);
|
2000-04-03 11:20:35 +00:00
|
|
|
nsAutoString shutdownString; shutdownString.AssignWithConversion(NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
2000-03-15 04:03:44 +00:00
|
|
|
|
|
|
|
if (topicString == shutdownString)
|
|
|
|
Shutdown();
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-05-09 19:04:13 +00:00
|
|
|
NS_IMPL_ISUPPORTS3(nsEventStateManager, nsIEventStateManager, nsIObserver, nsISupportsWeakReference)
|
1998-06-23 21:53:02 +00:00
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
|
2000-04-24 04:41:27 +00:00
|
|
|
nsEvent *aEvent,
|
1998-11-18 05:25:26 +00:00
|
|
|
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
|
|
|
|
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;
|
2001-01-20 04:59:39 +00:00
|
|
|
|
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:
|
2001-03-30 04:45:40 +00:00
|
|
|
BeginTrackingDragGesture ( aPresContext, (nsGUIEvent*)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:
|
2001-03-30 04:45:40 +00:00
|
|
|
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
|
|
|
KillClickHoldTimer();
|
|
|
|
#endif
|
1999-08-19 19:48:45 +00:00
|
|
|
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:
|
2000-02-24 03:41:14 +00:00
|
|
|
// on the Mac, GenerateDragGesture() may not return until the drag has completed
|
|
|
|
// and so |aTargetFrame| may have been deleted (moving a bookmark, for example).
|
|
|
|
// If this is the case, however, we know that ClearFrameRefs() has been called
|
|
|
|
// and it cleared out |mCurrentTarget|. As a result, we should pass |mCurrentTarget|
|
|
|
|
// into UpdateCursor().
|
2000-04-24 04:41:27 +00:00
|
|
|
GenerateDragGesture(aPresContext, (nsGUIEvent*)aEvent);
|
2000-02-24 03:41:14 +00:00
|
|
|
UpdateCursor(aPresContext, aEvent, mCurrentTarget, aStatus);
|
2000-04-24 04:41:27 +00:00
|
|
|
GenerateMouseEnterExit(aPresContext, (nsGUIEvent*)aEvent);
|
2001-01-20 04:59:39 +00:00
|
|
|
// Flush reflows and invalidates to eliminate flicker when both a reflow
|
|
|
|
// and visual change occur in an event callback. See bug #36849
|
|
|
|
FlushPendingEvents(aPresContext);
|
1998-11-18 05:25:26 +00:00
|
|
|
break;
|
|
|
|
case NS_MOUSE_EXIT:
|
2000-04-24 04:41:27 +00:00
|
|
|
GenerateMouseEnterExit(aPresContext, (nsGUIEvent*)aEvent);
|
2000-03-03 23:07:31 +00:00
|
|
|
//This is a window level mouseenter event and should stop here
|
|
|
|
aEvent->message = 0;
|
1998-11-18 05:25:26 +00:00
|
|
|
break;
|
1999-06-22 14:20:14 +00:00
|
|
|
case NS_DRAGDROP_OVER:
|
2000-04-24 04:41:27 +00:00
|
|
|
GenerateDragDropEnterExit(aPresContext, (nsGUIEvent*)aEvent);
|
1999-06-22 14:20:14 +00:00
|
|
|
break;
|
1998-11-18 05:25:26 +00:00
|
|
|
case NS_GOTFOCUS:
|
1999-11-13 05:16:33 +00:00
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
#ifdef DEBUG_hyatt
|
|
|
|
printf("Got focus.\n");
|
|
|
|
#endif
|
2000-02-11 23:41:13 +00:00
|
|
|
|
2000-06-28 20:35:32 +00:00
|
|
|
EnsureDocument(aPresContext);
|
1999-12-08 20:55:45 +00:00
|
|
|
|
1999-12-08 04:54:29 +00:00
|
|
|
if (gLastFocusedDocument == mDocument)
|
2001-06-18 07:34:41 +00:00
|
|
|
break;
|
|
|
|
|
1999-12-08 04:54:29 +00:00
|
|
|
//fire focus
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent focusevent;
|
|
|
|
focusevent.eventStructType = NS_EVENT;
|
|
|
|
focusevent.message = NS_FOCUS_CONTENT;
|
1999-11-13 05:16:33 +00:00
|
|
|
|
1999-12-08 04:54:29 +00:00
|
|
|
if (mDocument) {
|
2000-04-14 21:49:34 +00:00
|
|
|
|
2000-06-14 02:59:54 +00:00
|
|
|
if(gLastFocusedDocument) {
|
2000-04-14 21:49:34 +00:00
|
|
|
// fire a blur, on the document only to keep ender happy
|
|
|
|
nsEventStatus blurstatus = nsEventStatus_eIgnore;
|
|
|
|
nsEvent blurevent;
|
|
|
|
blurevent.eventStructType = NS_EVENT;
|
|
|
|
blurevent.message = NS_BLUR_CONTENT;
|
|
|
|
|
|
|
|
if(gLastFocusedPresContext) {
|
2000-11-04 08:21:20 +00:00
|
|
|
nsCOMPtr<nsIFocusController> focusController;
|
2000-06-23 05:37:08 +00:00
|
|
|
|
2000-05-03 00:49:37 +00:00
|
|
|
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
|
|
|
|
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
2000-09-01 01:54:35 +00:00
|
|
|
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
|
2000-05-03 00:49:37 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
|
|
|
|
if(ourWindow) {
|
2000-11-04 08:21:20 +00:00
|
|
|
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
|
|
|
|
if (focusController)
|
2001-04-18 01:41:20 +00:00
|
|
|
focusController->SetSuppressFocus(PR_TRUE, "NS_GOTFOCUS ESM Suppression");
|
2000-05-03 00:49:37 +00:00
|
|
|
}
|
|
|
|
|
2000-06-14 02:59:54 +00:00
|
|
|
gLastFocusedDocument->HandleDOMEvent(gLastFocusedPresContext, &blurevent, nsnull, NS_EVENT_FLAG_INIT, &blurstatus);
|
2001-06-18 07:34:41 +00:00
|
|
|
if (!mCurrentFocus && gLastFocusedContent) {
|
|
|
|
// must send it to the element that is losing focus,
|
|
|
|
// since SendFocusBlur wont be called
|
2000-06-14 02:59:54 +00:00
|
|
|
gLastFocusedContent->HandleDOMEvent(gLastFocusedPresContext, &blurevent, nsnull, NS_EVENT_FLAG_INIT, &blurstatus);
|
2000-06-29 05:27:05 +00:00
|
|
|
|
2001-04-24 22:52:03 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
gLastFocusedContent->GetDocument(*getter_AddRefs(doc));
|
|
|
|
if (doc) {
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
doc->GetShellAt(0, getter_AddRefs(shell));
|
2001-04-24 22:52:03 +00:00
|
|
|
if (shell) {
|
|
|
|
nsCOMPtr<nsIPresContext> oldPresContext;
|
|
|
|
shell->GetPresContext(getter_AddRefs(oldPresContext));
|
|
|
|
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
|
|
|
nsCOMPtr<nsIEventStateManager> esm;
|
|
|
|
oldPresContext->GetEventStateManager(getter_AddRefs(esm));
|
|
|
|
esm->SetFocusedContent(gLastFocusedContent);
|
|
|
|
gLastFocusedContent->HandleDOMEvent(oldPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
esm->SetFocusedContent(nsnull);
|
|
|
|
NS_IF_RELEASE(gLastFocusedContent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-11-04 08:21:20 +00:00
|
|
|
if (focusController) {
|
2001-04-18 01:41:20 +00:00
|
|
|
focusController->SetSuppressFocus(PR_FALSE, "NS_GOTFOCUS ESM Suppression");
|
2000-05-03 00:49:37 +00:00
|
|
|
}
|
2000-04-14 21:49:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-12-08 04:54:29 +00:00
|
|
|
// fire focus on window, not document
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
if (globalObject) {
|
|
|
|
nsIContent* currentFocus = mCurrentFocus;
|
2000-11-08 03:00:02 +00:00
|
|
|
mCurrentFocus = nsnull; // keep the owning reference in currentFocus
|
2000-06-29 05:27:05 +00:00
|
|
|
if(gLastFocusedDocument != mDocument) {
|
2000-06-09 21:13:03 +00:00
|
|
|
mDocument->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, &status);
|
2000-06-29 05:27:05 +00:00
|
|
|
if (currentFocus && currentFocus != gLastFocusedContent)
|
|
|
|
currentFocus->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
2000-06-09 21:13:03 +00:00
|
|
|
|
2001-02-15 05:07:46 +00:00
|
|
|
globalObject->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, &status);
|
2000-11-08 03:00:02 +00:00
|
|
|
NS_IF_RELEASE(mCurrentFocus);
|
|
|
|
mCurrentFocus = currentFocus; // we kept this reference above
|
2000-06-29 05:27:05 +00:00
|
|
|
NS_IF_RELEASE(gLastFocusedContent);
|
|
|
|
gLastFocusedContent = mCurrentFocus;
|
|
|
|
NS_IF_ADDREF(gLastFocusedContent);
|
1999-12-08 04:54:29 +00:00
|
|
|
}
|
|
|
|
|
1999-12-18 04:02:28 +00:00
|
|
|
|
1999-12-08 04:54:29 +00:00
|
|
|
NS_IF_RELEASE(gLastFocusedDocument);
|
|
|
|
gLastFocusedDocument = mDocument;
|
|
|
|
gLastFocusedPresContext = aPresContext;
|
|
|
|
NS_IF_ADDREF(gLastFocusedDocument);
|
1999-11-13 05:16:33 +00:00
|
|
|
}
|
|
|
|
}
|
2001-02-15 05:07:46 +00:00
|
|
|
|
|
|
|
// Set mBrowseWithCaret to value of preference if we're in HTML (don't use caret in XUL)
|
|
|
|
if (mDocument) {
|
|
|
|
mBrowseWithCaret = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
|
|
|
if (htmlDoc)
|
|
|
|
mPrefService->GetBoolPref("accessibility.browsewithcaret", &mBrowseWithCaret);
|
|
|
|
}
|
|
|
|
|
1999-11-13 05:16:33 +00:00
|
|
|
break;
|
2001-02-15 05:07:46 +00:00
|
|
|
|
1999-11-13 05:16:33 +00:00
|
|
|
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.
|
2001-05-18 12:07:42 +00:00
|
|
|
#ifdef XP_WIN
|
|
|
|
if(! NS_STATIC_CAST(nsFocusEvent*, aEvent)->isMozWindowTakingFocus) {
|
|
|
|
EnsureDocument(aPresContext);
|
|
|
|
|
|
|
|
// We can get a deactivate on an Ender widget. In this
|
|
|
|
// case, we would like to obtain the DOM Window to start
|
|
|
|
// with by looking at gLastFocusedContent.
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
|
|
|
|
if (gLastFocusedContent) {
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
gLastFocusedContent->GetDocument(*getter_AddRefs(doc));
|
|
|
|
if(doc)
|
|
|
|
doc->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
|
|
|
else {
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
|
|
|
NS_RELEASE(gLastFocusedContent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else mDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
|
|
|
|
|
|
|
// Now fire blurs. We have to fire a blur on the focused window
|
|
|
|
// and on the focused element if there is one.
|
|
|
|
if (gLastFocusedDocument && gLastFocusedPresContext) {
|
|
|
|
// Blur the element.
|
|
|
|
if (gLastFocusedContent) {
|
|
|
|
// Retrieve this content node's pres context. it can be out of sync in
|
|
|
|
// the Ender widget case.
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
gLastFocusedContent->GetDocument(*getter_AddRefs(doc));
|
|
|
|
if (doc) {
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
doc->GetShellAt(0, getter_AddRefs(shell));
|
2001-05-18 12:07:42 +00:00
|
|
|
if (shell) {
|
|
|
|
nsCOMPtr<nsIPresContext> oldPresContext;
|
|
|
|
shell->GetPresContext(getter_AddRefs(oldPresContext));
|
|
|
|
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
|
|
|
nsCOMPtr<nsIEventStateManager> esm;
|
|
|
|
oldPresContext->GetEventStateManager(getter_AddRefs(esm));
|
|
|
|
esm->SetFocusedContent(gLastFocusedContent);
|
|
|
|
gLastFocusedContent->HandleDOMEvent(oldPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
esm->SetFocusedContent(nsnull);
|
|
|
|
NS_IF_RELEASE(gLastFocusedContent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
|
|
|
|
|
|
|
// fire blur on document and window
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
if(gLastFocusedDocument) {
|
|
|
|
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
gLastFocusedDocument->HandleDOMEvent(gLastFocusedPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
if(globalObject)
|
|
|
|
globalObject->HandleDOMEvent(gLastFocusedPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
|
|
|
// Now clear our our global variables
|
|
|
|
mCurrentTarget = nsnull;
|
|
|
|
NS_IF_RELEASE(gLastFocusedDocument);
|
|
|
|
gLastFocusedPresContext = nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2001-05-18 12:59:32 +00:00
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
break;
|
2001-02-15 05:07:46 +00:00
|
|
|
|
1999-11-13 05:16:33 +00:00
|
|
|
case NS_ACTIVATE:
|
1999-07-27 20:55:03 +00:00
|
|
|
{
|
2000-02-11 23:41:13 +00:00
|
|
|
// If we have a command dispatcher, and if it has a focused window and a
|
|
|
|
// focused element in its focus memory, then restore the focus to those
|
|
|
|
// objects.
|
2000-06-28 20:35:32 +00:00
|
|
|
EnsureDocument(aPresContext);
|
2001-04-20 00:16:39 +00:00
|
|
|
#ifdef DEBUG_hyatt
|
|
|
|
printf("ESM: GOT ACTIVATE.\n");
|
|
|
|
#endif
|
2000-11-04 08:21:20 +00:00
|
|
|
nsCOMPtr<nsIFocusController> focusController;
|
2000-02-11 23:41:13 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> focusedElement;
|
2000-09-01 01:54:35 +00:00
|
|
|
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
|
2000-02-11 23:41:13 +00:00
|
|
|
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(mDocument);
|
2000-02-26 01:02:31 +00:00
|
|
|
|
2000-11-04 08:21:20 +00:00
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObj;
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObj));
|
|
|
|
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(globalObj));
|
2001-05-11 06:22:11 +00:00
|
|
|
NS_ASSERTION(win, "win is null. this happens [often on xlib builds]. see bug #79213");
|
|
|
|
if (!win) return NS_ERROR_NULL_POINTER;
|
2000-11-04 08:21:20 +00:00
|
|
|
win->GetRootFocusController(getter_AddRefs(focusController));
|
|
|
|
|
|
|
|
if (focusController) {
|
|
|
|
// Obtain focus info from the command dispatcher.
|
|
|
|
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
|
|
|
|
focusController->GetFocusedElement(getter_AddRefs(focusedElement));
|
2001-02-15 05:07:46 +00:00
|
|
|
|
2000-11-04 08:21:20 +00:00
|
|
|
focusController->SetSuppressFocusScroll(PR_TRUE);
|
2001-04-20 00:16:39 +00:00
|
|
|
focusController->SetActive(PR_TRUE);
|
2000-02-11 23:41:13 +00:00
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
if (!focusedWindow) {
|
2000-11-04 08:21:20 +00:00
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
focusedWindow = do_QueryInterface(globalObject);
|
1999-06-15 03:14:28 +00:00
|
|
|
}
|
2000-02-11 23:41:13 +00:00
|
|
|
|
|
|
|
// Focus the DOM window.
|
2000-07-28 21:48:08 +00:00
|
|
|
NS_WARN_IF_FALSE(focusedWindow,"check why focusedWindow is null!!!");
|
|
|
|
if(focusedWindow) {
|
2000-06-23 22:18:54 +00:00
|
|
|
focusedWindow->Focus();
|
2000-02-11 23:41:13 +00:00
|
|
|
|
2000-07-28 21:48:08 +00:00
|
|
|
if (focusedElement) {
|
|
|
|
nsCOMPtr<nsIContent> focusContent = do_QueryInterface(focusedElement);
|
|
|
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
focusedWindow->GetDocument(getter_AddRefs(domDoc));
|
|
|
|
if (domDoc) {
|
|
|
|
document = do_QueryInterface(domDoc);
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
nsCOMPtr<nsIPresContext> context;
|
2001-06-20 03:27:48 +00:00
|
|
|
document->GetShellAt(0, getter_AddRefs(shell));
|
2000-07-28 21:48:08 +00:00
|
|
|
shell->GetPresContext(getter_AddRefs(context));
|
|
|
|
focusContent->SetFocus(context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-02-11 23:41:13 +00:00
|
|
|
|
2000-11-04 08:21:20 +00:00
|
|
|
if (focusController) {
|
2000-09-15 07:02:58 +00:00
|
|
|
PRBool isSuppressed;
|
2000-11-04 08:21:20 +00:00
|
|
|
focusController->GetSuppressFocus(&isSuppressed);
|
2000-09-15 07:02:58 +00:00
|
|
|
while(isSuppressed){
|
2001-04-18 01:41:20 +00:00
|
|
|
focusController->SetSuppressFocus(PR_FALSE, "Activation Suppression"); // Unsuppress and let the command dispatcher listen again.
|
2000-11-04 08:21:20 +00:00
|
|
|
focusController->GetSuppressFocus(&isSuppressed);
|
2000-09-15 07:02:58 +00:00
|
|
|
}
|
2000-11-04 08:21:20 +00:00
|
|
|
focusController->SetSuppressFocusScroll(PR_FALSE);
|
2000-02-29 03:54:49 +00:00
|
|
|
}
|
1999-06-15 03:14:28 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
break;
|
1999-11-13 05:16:33 +00:00
|
|
|
|
|
|
|
case NS_DEACTIVATE:
|
1999-07-27 20:55:03 +00:00
|
|
|
{
|
2000-06-28 20:35:32 +00:00
|
|
|
EnsureDocument(aPresContext);
|
2000-02-11 23:41:13 +00:00
|
|
|
|
2001-06-18 07:34:41 +00:00
|
|
|
if (gLastFocusedDocument != mDocument)
|
|
|
|
break;
|
|
|
|
|
2000-02-11 23:41:13 +00:00
|
|
|
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
|
2001-06-18 07:34:41 +00:00
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
|
|
|
|
2000-02-11 23:41:13 +00:00
|
|
|
// Suppress the command dispatcher for the duration of the
|
|
|
|
// de-activation. This will cause it to remember the last
|
|
|
|
// focused sub-window and sub-element for this top-level
|
|
|
|
// window.
|
2000-11-04 08:21:20 +00:00
|
|
|
nsCOMPtr<nsIFocusController> focusController;
|
2000-09-01 01:54:35 +00:00
|
|
|
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
|
2000-02-11 23:41:13 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
|
2000-03-21 00:47:19 +00:00
|
|
|
if(ourWindow) {
|
2000-11-04 08:21:20 +00:00
|
|
|
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
|
|
|
|
if (focusController) {
|
|
|
|
// Suppress the command dispatcher.
|
2001-04-18 01:41:20 +00:00
|
|
|
focusController->SetSuppressFocus(PR_TRUE, "Deactivate Suppression");
|
2000-02-11 23:41:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now fire blurs. We have to fire a blur on the focused window
|
|
|
|
// and on the focused element if there is one.
|
|
|
|
if (gLastFocusedDocument && gLastFocusedPresContext) {
|
|
|
|
if (gLastFocusedContent) {
|
2001-06-18 07:34:41 +00:00
|
|
|
// Blur the element.
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
gLastFocusedDocument->GetShellAt(0, getter_AddRefs(shell));
|
2001-06-18 07:34:41 +00:00
|
|
|
if (shell) {
|
|
|
|
nsCOMPtr<nsIPresContext> oldPresContext;
|
|
|
|
shell->GetPresContext(getter_AddRefs(oldPresContext));
|
|
|
|
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
|
|
|
nsCOMPtr<nsIEventStateManager> esm;
|
|
|
|
oldPresContext->GetEventStateManager(getter_AddRefs(esm));
|
|
|
|
esm->SetFocusedContent(gLastFocusedContent);
|
|
|
|
gLastFocusedContent->HandleDOMEvent(oldPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
esm->SetFocusedContent(nsnull);
|
|
|
|
NS_IF_RELEASE(gLastFocusedContent);
|
2000-02-11 23:41:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
|
|
|
|
|
|
|
// fire blur on document and window
|
2001-06-18 07:34:41 +00:00
|
|
|
mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
if (ourGlobal)
|
|
|
|
ourGlobal->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
|
2000-02-11 23:41:13 +00:00
|
|
|
// Now clear our our global variables
|
2000-03-21 00:47:19 +00:00
|
|
|
mCurrentTarget = nsnull;
|
|
|
|
NS_IF_RELEASE(gLastFocusedDocument);
|
2000-02-11 23:41:13 +00:00
|
|
|
gLastFocusedPresContext = nsnull;
|
|
|
|
}
|
|
|
|
|
2000-11-04 08:21:20 +00:00
|
|
|
if (focusController) {
|
|
|
|
focusController->SetActive(PR_FALSE);
|
2001-04-18 01:41:20 +00:00
|
|
|
focusController->SetSuppressFocus(PR_FALSE, "Deactivate Suppression");
|
2000-02-29 03:54:49 +00:00
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
}
|
2000-02-29 03:54:49 +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:
|
2000-05-16 10:22:20 +00:00
|
|
|
{
|
2000-06-02 14:20:50 +00:00
|
|
|
|
2000-05-16 10:22:20 +00:00
|
|
|
nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
|
2000-06-02 14:20:50 +00:00
|
|
|
#ifdef XP_MAC
|
2000-09-14 22:58:47 +00:00
|
|
|
// (pinkerton, joki, saari) IE5 for mac uses Control for access keys. The HTML4 spec
|
|
|
|
// suggests to use command on mac, but this really sucks (imagine someone having a "q"
|
|
|
|
// as an access key and not letting you quit the app!). As a result, we've made a
|
|
|
|
// command decision 1 day before tree lockdown to change it to the control key.
|
|
|
|
PRBool isSpecialAccessKeyDown = keyEvent->isControl;
|
2000-06-02 14:20:50 +00:00
|
|
|
#else
|
|
|
|
PRBool isSpecialAccessKeyDown = keyEvent->isAlt;
|
|
|
|
#endif
|
2000-05-16 10:22:20 +00:00
|
|
|
//This is to prevent keyboard scrolling while alt modifier in use.
|
2000-06-02 14:20:50 +00:00
|
|
|
if (isSpecialAccessKeyDown) {
|
2000-05-16 10:22:20 +00:00
|
|
|
//Alt key is down, we may need to do an accesskey
|
|
|
|
if (mAccessKeys) {
|
|
|
|
//Someone registered an accesskey. Find and activate it.
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
nsAutoString accKey((char)keyEvent->charCode);
|
|
|
|
accKey.ToLowerCase();
|
|
|
|
|
|
|
|
nsVoidKey key((void*)accKey.First());
|
2000-05-16 10:22:20 +00:00
|
|
|
if (mAccessKeys->Exists(&key)) {
|
|
|
|
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key)));
|
|
|
|
|
|
|
|
//Its hard to say what HTML4 wants us to do in all cases. So for now we'll settle for
|
|
|
|
//A) Set focus
|
|
|
|
ChangeFocus(content, nsnull, PR_TRUE);
|
|
|
|
|
2001-05-23 06:35:32 +00:00
|
|
|
nsresult rv = getPrefService();
|
|
|
|
PRBool activate = PR_TRUE;
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mPrefService->GetBoolPref("accessibility.accesskeycausesactivation", &activate);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (activate) {
|
|
|
|
//B) Click on it if the users prefs indicate to do so.
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_MOUSE_EVENT;
|
|
|
|
event.message = NS_MOUSE_LEFT_CLICK;
|
|
|
|
event.isShift = PR_FALSE;
|
|
|
|
event.isControl = PR_FALSE;
|
|
|
|
event.isAlt = PR_FALSE;
|
|
|
|
event.isMeta = PR_FALSE;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.widget = nsnull;
|
|
|
|
content->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
2000-05-16 10:22:20 +00:00
|
|
|
|
|
|
|
*aStatus = nsEventStatus_eConsumeNoDefault;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
|
2001-03-30 04:45:40 +00:00
|
|
|
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// CreateClickHoldTimer
|
|
|
|
//
|
|
|
|
// Fire off a timer for determining if the user wants click-hold. This timer
|
|
|
|
// is a one-shot that will be cancelled when the user moves enough to fire
|
|
|
|
// a drag.
|
|
|
|
//
|
|
|
|
void
|
|
|
|
nsEventStateManager :: CreateClickHoldTimer ( nsIPresContext* inPresContext, nsGUIEvent* inMouseDownEvent )
|
|
|
|
{
|
|
|
|
// just to be anal (er, safe)
|
|
|
|
if ( mClickHoldTimer ) {
|
|
|
|
mClickHoldTimer->Cancel();
|
|
|
|
mClickHoldTimer = nsnull;
|
|
|
|
}
|
|
|
|
|
2001-04-26 19:12:31 +00:00
|
|
|
// if content clicked on has a popup, don't even start the timer
|
|
|
|
// since we'll end up conflicting and both will show.
|
|
|
|
nsCOMPtr<nsIContent> clickedContent;
|
|
|
|
if ( mGestureDownFrame ) {
|
|
|
|
mGestureDownFrame->GetContent(getter_AddRefs(clickedContent));
|
|
|
|
if ( clickedContent ) {
|
|
|
|
// check for the |popup| attribute
|
|
|
|
nsAutoString popup;
|
|
|
|
clickedContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::popup, popup);
|
|
|
|
if ( popup != NS_LITERAL_STRING("") )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// check for a <menubutton> like bookmarks
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
clickedContent->GetTag ( *getter_AddRefs(tag) );
|
|
|
|
if ( tag == nsXULAtoms::menubutton )
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-30 04:45:40 +00:00
|
|
|
mClickHoldTimer = do_CreateInstance("@mozilla.org/timer;1");
|
|
|
|
if ( mClickHoldTimer )
|
|
|
|
mClickHoldTimer->Init(sClickHoldCallback, this, kClickHoldDelay, NS_PRIORITY_HIGH);
|
|
|
|
|
|
|
|
mEventPoint = inMouseDownEvent->point;
|
|
|
|
mEventRefPoint = inMouseDownEvent->refPoint;
|
|
|
|
mEventDownWidget = inMouseDownEvent->widget;
|
|
|
|
|
|
|
|
mEventPresContext = inPresContext;
|
|
|
|
|
|
|
|
} // CreateClickHoldTimer
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// KillClickHoldTimer
|
|
|
|
//
|
|
|
|
// Stop the timer that would show the context menu dead in its tracks
|
|
|
|
//
|
|
|
|
void
|
|
|
|
nsEventStateManager :: KillClickHoldTimer ( )
|
|
|
|
{
|
|
|
|
if ( mClickHoldTimer ) {
|
|
|
|
mClickHoldTimer->Cancel();
|
|
|
|
mClickHoldTimer = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
mEventDownWidget = nsnull;
|
|
|
|
mEventPresContext = nsnull;
|
|
|
|
|
|
|
|
} // KillTooltipTimer
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// sClickHoldCallback
|
|
|
|
//
|
|
|
|
// This fires after the mouse has been down for a certain length of time.
|
|
|
|
//
|
|
|
|
void
|
|
|
|
nsEventStateManager :: sClickHoldCallback ( nsITimer *aTimer, void* aESM )
|
|
|
|
{
|
|
|
|
nsEventStateManager* self = NS_STATIC_CAST(nsEventStateManager*, aESM);
|
|
|
|
if ( self )
|
|
|
|
self->FireContextClick();
|
|
|
|
|
|
|
|
// NOTE: |aTimer| and |self->mAutoHideTimer| are invalid after calling ClosePopup();
|
|
|
|
|
|
|
|
} // sAutoHideCallback
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// FireContextClick
|
|
|
|
//
|
|
|
|
// If we're this far, our timer has fired, which means the mouse has been down
|
|
|
|
// for a certain period of time and has not moved enough to generate a dragGesture.
|
|
|
|
// We can be certain the user wants a context-click at this stage, so generate
|
|
|
|
// a dom event and fire it in.
|
|
|
|
//
|
|
|
|
// After the event fires, check if PreventDefault() has been set on the event which
|
|
|
|
// means that someone either ate the event or put up a context menu. This is our cue
|
|
|
|
// to stop tracking the drag gesture. If we always did this, draggable items w/out
|
|
|
|
// a context menu wouldn't be draggable after a certain length of time, which is
|
|
|
|
// _not_ what we want.
|
|
|
|
//
|
|
|
|
void
|
|
|
|
nsEventStateManager :: FireContextClick ( )
|
|
|
|
{
|
|
|
|
if ( !mEventDownWidget || !mEventPresContext )
|
|
|
|
return;
|
|
|
|
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_MOUSE_EVENT;
|
|
|
|
event.message = NS_CONTEXTMENU;
|
|
|
|
event.widget = mEventDownWidget;
|
|
|
|
event.clickCount = 1;
|
|
|
|
event.point = mEventPoint;
|
|
|
|
event.refPoint = mEventRefPoint;
|
|
|
|
event.isShift = PR_FALSE;
|
|
|
|
event.isControl = PR_FALSE;
|
|
|
|
event.isAlt = PR_FALSE;
|
|
|
|
event.isMeta = PR_FALSE;
|
|
|
|
|
|
|
|
// Dispatch to the DOM. We have to fake out the ESM and tell it that the
|
|
|
|
// current target frame is actually where the mouseDown occurred, otherwise it
|
|
|
|
// will use the frame the mouse is currently over which may or may not be
|
|
|
|
// the same. (Note: saari and I have decided that we don't have to reset |mCurrentTarget|
|
|
|
|
// when we're through because no one else is doing anything more with this
|
|
|
|
// event and it will get reset on the very next event to the correct frame).
|
|
|
|
mCurrentTarget = mGestureDownFrame;
|
|
|
|
nsCOMPtr<nsIContent> lastContent;
|
|
|
|
if ( mGestureDownFrame ) {
|
|
|
|
mGestureDownFrame->GetContent(getter_AddRefs(lastContent));
|
|
|
|
|
|
|
|
if ( lastContent ) {
|
|
|
|
// before dispatching, check that we're not on something that doesn't get a context menu
|
|
|
|
PRBool allowedToDispatch = PR_TRUE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
lastContent->GetTag ( *getter_AddRefs(tag) );
|
2001-03-31 23:32:14 +00:00
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> inputElm ( do_QueryInterface(lastContent) );
|
|
|
|
nsCOMPtr<nsIFormControl> formControl ( do_QueryInterface(lastContent) );
|
|
|
|
if ( inputElm ) {
|
2001-03-31 23:50:25 +00:00
|
|
|
// of all input elements, only ones dealing with text are allowed to have context menus
|
|
|
|
if ( tag == nsHTMLAtoms::input ) {
|
2001-03-31 23:32:14 +00:00
|
|
|
nsAutoString type;
|
|
|
|
lastContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, type);
|
|
|
|
if ( type != NS_LITERAL_STRING("") && type != NS_LITERAL_STRING("text") &&
|
|
|
|
type != NS_LITERAL_STRING("password") && type != NS_LITERAL_STRING("file") )
|
|
|
|
allowedToDispatch = PR_FALSE;
|
|
|
|
}
|
2001-03-30 04:45:40 +00:00
|
|
|
}
|
2001-03-31 23:32:14 +00:00
|
|
|
else if ( formControl ) // catches combo-boxes
|
|
|
|
allowedToDispatch = PR_FALSE;
|
|
|
|
else if ( tag == nsXULAtoms::scrollbar || tag == nsXULAtoms::scrollbarbutton || tag == nsXULAtoms::button )
|
2001-03-30 04:45:40 +00:00
|
|
|
allowedToDispatch = PR_FALSE;
|
2001-06-04 22:39:49 +00:00
|
|
|
else if ( tag == nsHTMLAtoms::applet || tag == nsHTMLAtoms::object || tag == nsHTMLAtoms::embed )
|
|
|
|
allowedToDispatch = PR_FALSE;
|
2001-03-30 04:45:40 +00:00
|
|
|
|
|
|
|
if ( allowedToDispatch ) {
|
|
|
|
// stop selection tracking, we're in control now
|
|
|
|
nsCOMPtr<nsIFrameSelection> frameSel;
|
|
|
|
GetSelection ( mGestureDownFrame, mEventPresContext, getter_AddRefs(frameSel) );
|
|
|
|
if ( frameSel ) {
|
|
|
|
PRBool mouseDownState = PR_TRUE;
|
|
|
|
frameSel->GetMouseDownState(&mouseDownState);
|
|
|
|
if (mouseDownState)
|
|
|
|
frameSel->SetMouseDownState(PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// dispatch to DOM
|
|
|
|
lastContent->HandleDOMEvent(mEventPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
|
|
|
|
// dispatch to the frame
|
|
|
|
mGestureDownFrame->HandleEvent(mEventPresContext, &event, &status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// now check if the event has been handled. If so, stop tracking a drag
|
|
|
|
if ( status == nsEventStatus_eConsumeNoDefault )
|
|
|
|
StopTrackingDragGesture();
|
|
|
|
|
|
|
|
KillClickHoldTimer();
|
|
|
|
|
|
|
|
} // FireContextClick
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
//
|
2001-03-30 04:45:40 +00:00
|
|
|
// We also use this to track click-hold context menus on mac. When the mouse goes down,
|
|
|
|
// fire off a short timer. If the timer goes off and we have yet to fire the
|
|
|
|
// drag gesture (ie, the mouse hasn't moved a certain distance), then we can
|
|
|
|
// assume the user wants a click-hold, so fire a context-click event. We only
|
|
|
|
// want to cancel the drag gesture if the context-click event is handled.
|
|
|
|
//
|
1999-08-19 19:48:45 +00:00
|
|
|
void
|
2001-03-30 04:45:40 +00:00
|
|
|
nsEventStateManager :: BeginTrackingDragGesture ( nsIPresContext* aPresContext, nsGUIEvent* inDownEvent, nsIFrame* inDownFrame )
|
1999-08-19 19:48:45 +00:00
|
|
|
{
|
|
|
|
mIsTrackingDragGesture = PR_TRUE;
|
|
|
|
mGestureDownPoint = inDownEvent->point;
|
|
|
|
mGestureDownFrame = inDownFrame;
|
2001-03-30 04:45:40 +00:00
|
|
|
|
|
|
|
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
|
|
|
// fire off a timer to track click-hold
|
|
|
|
CreateClickHoldTimer ( aPresContext, inDownEvent );
|
|
|
|
#endif
|
|
|
|
|
1999-08-19 19:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-03-30 04:45:40 +00:00
|
|
|
//
|
|
|
|
// GetSelection
|
|
|
|
//
|
|
|
|
// Helper routine to get an nsIFrameSelection from the given frame
|
|
|
|
//
|
|
|
|
void
|
|
|
|
nsEventStateManager :: GetSelection ( nsIFrame* inFrame, nsIPresContext* inPresContext, nsIFrameSelection** outSelection )
|
|
|
|
{
|
|
|
|
*outSelection = nsnull;
|
|
|
|
|
|
|
|
if (inFrame) {
|
|
|
|
nsCOMPtr<nsISelectionController> selCon;
|
|
|
|
nsresult rv = inFrame->GetSelectionController(inPresContext, getter_AddRefs(selCon));
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv) && selCon) {
|
|
|
|
nsCOMPtr<nsIFrameSelection> frameSel;
|
|
|
|
|
|
|
|
frameSel = do_QueryInterface(selCon);
|
|
|
|
|
|
|
|
if (! frameSel) {
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
rv = inPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv) && shell)
|
2001-04-02 18:18:53 +00:00
|
|
|
rv = shell->GetFrameSelection(getter_AddRefs(frameSel));
|
2001-03-30 04:45:40 +00:00
|
|
|
}
|
2001-04-02 18:18:53 +00:00
|
|
|
|
|
|
|
*outSelection = frameSel.get();
|
|
|
|
NS_IF_ADDREF(*outSelection);
|
2001-03-30 04:45:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // GetSelection
|
|
|
|
|
|
|
|
|
1999-08-19 19:48:45 +00:00
|
|
|
//
|
|
|
|
// 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() ) {
|
2000-05-25 20:04:02 +00:00
|
|
|
|
|
|
|
// Check if selection is tracking drag gestures, if so
|
|
|
|
// don't interfere!
|
2001-03-30 04:45:40 +00:00
|
|
|
nsCOMPtr<nsIFrameSelection> frameSel;
|
|
|
|
GetSelection ( mGestureDownFrame, aPresContext, getter_AddRefs(frameSel) );
|
|
|
|
if ( frameSel ) {
|
|
|
|
PRBool mouseDownState = PR_TRUE;
|
|
|
|
frameSel->GetMouseDownState(&mouseDownState);
|
|
|
|
if (mouseDownState) {
|
|
|
|
StopTrackingDragGesture();
|
|
|
|
return;
|
2000-05-25 20:04:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-08-19 19:48:45 +00:00
|
|
|
// 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 ) {
|
2001-03-30 04:45:40 +00:00
|
|
|
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
|
|
|
// stop the click-hold before we fire off the drag gesture, in case
|
|
|
|
// it takes a long time
|
|
|
|
KillClickHoldTimer();
|
|
|
|
#endif
|
|
|
|
|
1999-08-19 19:48:45 +00:00
|
|
|
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;
|
2000-01-15 17:21:20 +00:00
|
|
|
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
|
|
|
|
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
|
|
|
|
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
|
|
|
|
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
|
1999-08-19 19:48:45 +00:00
|
|
|
|
2000-08-01 00:35:23 +00:00
|
|
|
// Dispatch to the DOM. We have to fake out the ESM and tell it that the
|
|
|
|
// current target frame is actually where the mouseDown occurred, otherwise it
|
|
|
|
// will use the frame the mouse is currently over which may or may not be
|
|
|
|
// the same. (Note: saari and I have decided that we don't have to reset |mCurrentTarget|
|
|
|
|
// when we're through because no one else is doing anything more with this
|
|
|
|
// event and it will get reset on the very next event to the correct frame).
|
|
|
|
mCurrentTarget = mGestureDownFrame;
|
1999-08-19 19:48:45 +00:00
|
|
|
nsCOMPtr<nsIContent> lastContent;
|
1999-11-09 07:10:46 +00:00
|
|
|
if ( mGestureDownFrame ) {
|
2000-02-11 01:24:59 +00:00
|
|
|
mGestureDownFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
|
1999-11-09 07:10:46 +00:00
|
|
|
if ( lastContent )
|
2000-08-01 00:35:23 +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
|
2000-08-14 22:29:03 +00:00
|
|
|
if ( mGestureDownFrame )
|
1999-11-24 06:03:41 +00:00
|
|
|
mGestureDownFrame->HandleEvent(aPresContext, &event, &status);
|
2000-08-14 22:29:03 +00:00
|
|
|
|
2000-08-01 00:35:23 +00:00
|
|
|
StopTrackingDragGesture();
|
1999-08-19 19:48:45 +00:00
|
|
|
}
|
|
|
|
}
|
2000-10-16 21:52:22 +00:00
|
|
|
|
|
|
|
// Now flush all pending notifications.
|
2001-01-20 04:59:39 +00:00
|
|
|
FlushPendingEvents(aPresContext);
|
1999-08-19 19:48:45 +00:00
|
|
|
} // GenerateDragGesture
|
|
|
|
|
2000-05-15 02:10:11 +00:00
|
|
|
nsresult
|
|
|
|
nsEventStateManager::ChangeTextSize(PRInt32 change)
|
|
|
|
{
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!gLastFocusedDocument) return NS_ERROR_FAILURE;
|
|
|
|
|
2000-08-06 04:15:02 +00:00
|
|
|
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
|
|
|
|
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!ourGlobal) return NS_ERROR_FAILURE;
|
|
|
|
|
2000-08-06 04:15:02 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!ourWindow) return NS_ERROR_FAILURE;
|
2000-08-06 04:15:02 +00:00
|
|
|
|
2000-09-10 05:35:36 +00:00
|
|
|
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
|
2000-08-06 04:15:02 +00:00
|
|
|
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!rootWindow) return NS_ERROR_FAILURE;
|
2000-08-06 04:15:02 +00:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsCOMPtr<nsIDOMWindow> windowContent;
|
|
|
|
rootWindow->GetContent(getter_AddRefs(windowContent));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!windowContent) return NS_ERROR_FAILURE;
|
2000-08-06 04:15:02 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
|
|
windowContent->GetDocument(getter_AddRefs(domDoc));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!domDoc) return NS_ERROR_FAILURE;
|
2000-08-06 04:15:02 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!doc) return NS_ERROR_FAILURE;
|
2000-08-06 04:15:02 +00:00
|
|
|
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
doc->GetShellAt(0, getter_AddRefs(presShell));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!presShell) return NS_ERROR_FAILURE;
|
2000-08-06 04:15:02 +00:00
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
presShell->GetPresContext(getter_AddRefs(presContext));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!presContext) return NS_ERROR_FAILURE;
|
2000-08-06 04:15:02 +00:00
|
|
|
|
2000-05-15 02:10:11 +00:00
|
|
|
nsCOMPtr<nsISupports> pcContainer;
|
2000-08-06 04:15:02 +00:00
|
|
|
presContext->GetContainer(getter_AddRefs(pcContainer));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!pcContainer) return NS_ERROR_FAILURE;
|
2000-05-15 02:10:11 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> docshell(do_QueryInterface(pcContainer));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!docshell) return NS_ERROR_FAILURE;
|
2000-05-15 02:10:11 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIContentViewer> cv;
|
|
|
|
docshell->GetContentViewer(getter_AddRefs(cv));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!cv) return NS_ERROR_FAILURE;
|
2000-05-15 02:10:11 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIMarkupDocumentViewer> mv(do_QueryInterface(cv));
|
2000-09-10 05:35:36 +00:00
|
|
|
if(!mv) return NS_ERROR_FAILURE;
|
2000-05-15 02:10:11 +00:00
|
|
|
|
|
|
|
float textzoom;
|
|
|
|
mv->GetTextZoom(&textzoom);
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
textzoom += ((float)change) / 10;
|
2001-01-05 23:06:09 +00:00
|
|
|
if (textzoom > 0 && textzoom <= 20)
|
|
|
|
mv->SetTextZoom(textzoom);
|
2000-05-15 02:10:11 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-08-19 19:48:45 +00:00
|
|
|
|
2001-02-15 22:07:06 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// DoTreeScroll
|
|
|
|
//
|
|
|
|
// Trees know best how to deal with scrolling, so use the tree scroll api's instead
|
|
|
|
// of just blindly scrolling the view.
|
|
|
|
//
|
|
|
|
nsresult
|
|
|
|
nsEventStateManager::DoTreeScroll(nsIPresContext* inPresContext, PRInt32 inNumLines,
|
|
|
|
PRBool inScrollPage, nsITreeFrame* inTreeFrame)
|
|
|
|
{
|
|
|
|
PRInt32 scrollIndex, visibleRows;
|
|
|
|
inTreeFrame->GetIndexOfFirstVisibleRow(&scrollIndex);
|
|
|
|
inTreeFrame->GetNumberOfVisibleRows(&visibleRows);
|
|
|
|
|
|
|
|
if (inScrollPage)
|
|
|
|
scrollIndex += ((inNumLines > 0) ? visibleRows : -visibleRows);
|
|
|
|
else
|
|
|
|
scrollIndex += inNumLines;
|
|
|
|
|
|
|
|
if (scrollIndex < 0)
|
|
|
|
scrollIndex = 0;
|
|
|
|
else {
|
|
|
|
PRInt32 numRows;
|
|
|
|
inTreeFrame->GetRowCount(&numRows);
|
|
|
|
PRInt32 lastPageTopRow = numRows - visibleRows;
|
|
|
|
if (scrollIndex > lastPageTopRow)
|
|
|
|
scrollIndex = lastPageTopRow;
|
|
|
|
}
|
|
|
|
|
|
|
|
inTreeFrame->ScrollToIndex(scrollIndex);
|
|
|
|
|
|
|
|
// we have to do a sync update for mac because if we scroll too quickly
|
|
|
|
// w/out going back to the main event loop we can easily scroll the wrong
|
|
|
|
// bits and it looks like garbage (bug 63465).
|
|
|
|
nsIFrame* frame = nsnull;
|
2001-02-19 12:55:42 +00:00
|
|
|
if ( NS_SUCCEEDED(inTreeFrame->QueryInterface(NS_GET_IID(nsIFrame),
|
|
|
|
(void **)&frame)) ) {
|
2001-02-15 22:07:06 +00:00
|
|
|
nsIView* treeView = nsnull;
|
|
|
|
frame->GetView(inPresContext, &treeView);
|
|
|
|
if (!treeView) {
|
|
|
|
nsIFrame* frameWithView;
|
|
|
|
frame->GetParentWithView(inPresContext, &frameWithView);
|
|
|
|
if (frameWithView)
|
|
|
|
frameWithView->GetView(inPresContext, &treeView);
|
|
|
|
else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
if (treeView)
|
|
|
|
ForceViewUpdate(treeView);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
} // DoTreeScroll
|
|
|
|
|
|
|
|
|
2000-12-09 07:28:19 +00:00
|
|
|
nsresult
|
|
|
|
nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aTargetFrame,
|
|
|
|
nsMouseScrollEvent* msEvent,
|
|
|
|
PRInt32 numLines, PRBool scrollPage,
|
|
|
|
PRBool aUseTargetFrame)
|
|
|
|
{
|
|
|
|
nsIView* focusView = nsnull;
|
|
|
|
nsIScrollableView* sv = nsnull;
|
|
|
|
nsIFrame* focusFrame = nsnull;
|
|
|
|
|
|
|
|
// Special case for tree/list frames - they handle their own scrolling
|
|
|
|
nsITreeFrame* treeFrame = nsnull;
|
2001-03-06 22:16:42 +00:00
|
|
|
nsCOMPtr<nsIOutlinerBoxObject> outlinerBoxObject;
|
2000-12-09 07:28:19 +00:00
|
|
|
nsIFrame* curFrame = aTargetFrame;
|
|
|
|
|
|
|
|
while (curFrame) {
|
|
|
|
if (NS_OK == curFrame->QueryInterface(NS_GET_IID(nsITreeFrame),
|
|
|
|
(void**) &treeFrame))
|
|
|
|
break;
|
2001-03-06 22:16:42 +00:00
|
|
|
|
|
|
|
outlinerBoxObject = do_QueryInterface(curFrame);
|
|
|
|
if (outlinerBoxObject)
|
|
|
|
break;
|
|
|
|
|
2000-12-09 07:28:19 +00:00
|
|
|
curFrame->GetParent(&curFrame);
|
|
|
|
}
|
2001-03-06 22:16:42 +00:00
|
|
|
|
2001-04-30 08:11:03 +00:00
|
|
|
// Create a mouseout event that we fire to the content before
|
|
|
|
// scrolling, to allow tooltips to disappear, etc.
|
|
|
|
|
|
|
|
nsMouseEvent mouseOutEvent;
|
|
|
|
mouseOutEvent.eventStructType = NS_MOUSE_EVENT;
|
|
|
|
mouseOutEvent.message = NS_MOUSE_EXIT_SYNTH;
|
|
|
|
mouseOutEvent.widget = msEvent->widget;
|
|
|
|
mouseOutEvent.clickCount = 0;
|
|
|
|
mouseOutEvent.point = nsPoint(0,0);
|
|
|
|
mouseOutEvent.refPoint = nsPoint(0,0);
|
|
|
|
mouseOutEvent.isShift = PR_FALSE;
|
|
|
|
mouseOutEvent.isControl = PR_FALSE;
|
|
|
|
mouseOutEvent.isAlt = PR_FALSE;
|
|
|
|
mouseOutEvent.isMeta = PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> targetContent;
|
|
|
|
aTargetFrame->GetContent(getter_AddRefs(targetContent));
|
|
|
|
|
|
|
|
nsEventStatus mouseoutStatus = nsEventStatus_eIgnore;
|
2001-03-06 22:16:42 +00:00
|
|
|
|
2001-04-30 08:11:03 +00:00
|
|
|
if (treeFrame) {
|
|
|
|
if (targetContent)
|
|
|
|
targetContent->HandleDOMEvent(aPresContext, &mouseOutEvent, nsnull,
|
|
|
|
NS_EVENT_FLAG_INIT, &mouseoutStatus);
|
|
|
|
return DoTreeScroll(aPresContext, numLines, scrollPage, treeFrame);
|
|
|
|
} else if (outlinerBoxObject) {
|
|
|
|
if (targetContent)
|
|
|
|
targetContent->HandleDOMEvent(aPresContext, &mouseOutEvent, nsnull,
|
|
|
|
NS_EVENT_FLAG_INIT, &mouseoutStatus);
|
2001-03-06 22:16:42 +00:00
|
|
|
if (scrollPage)
|
|
|
|
outlinerBoxObject->ScrollByPages((numLines > 0) ? 1 : -1);
|
|
|
|
else
|
|
|
|
outlinerBoxObject->ScrollByLines(numLines);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-12-09 07:28:19 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
|
|
|
|
// Otherwise, check for a focused content element
|
|
|
|
nsCOMPtr<nsIContent> focusContent;
|
|
|
|
if (mCurrentFocus) {
|
|
|
|
focusContent = mCurrentFocus;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// If there is no focused content, get the document content
|
|
|
|
EnsureDocument(presShell);
|
2001-06-20 03:27:48 +00:00
|
|
|
mDocument->GetRootContent(getter_AddRefs(focusContent));
|
2000-12-09 07:28:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!focusContent)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
if (aUseTargetFrame)
|
|
|
|
focusFrame = aTargetFrame;
|
|
|
|
else
|
|
|
|
presShell->GetPrimaryFrameFor(focusContent, &focusFrame);
|
|
|
|
|
|
|
|
if (!focusFrame)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
// Now check whether this frame wants to provide us with an
|
|
|
|
// nsIScrollableView to use for scrolling.
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScrollableViewProvider> svp = do_QueryInterface(focusFrame);
|
|
|
|
if (svp) {
|
|
|
|
svp->GetScrollableView(&sv);
|
2001-01-04 22:24:07 +00:00
|
|
|
if (sv)
|
|
|
|
sv->QueryInterface(NS_GET_IID(nsIView), (void**) &focusView);
|
2000-12-09 07:28:19 +00:00
|
|
|
} else {
|
|
|
|
focusFrame->GetView(aPresContext, &focusView);
|
|
|
|
if (!focusView) {
|
|
|
|
nsIFrame* frameWithView;
|
|
|
|
focusFrame->GetParentWithView(aPresContext, &frameWithView);
|
|
|
|
if (frameWithView)
|
|
|
|
frameWithView->GetView(aPresContext, &focusView);
|
|
|
|
else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
sv = GetNearestScrollingView(focusView);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sv) {
|
2001-04-30 08:11:03 +00:00
|
|
|
if (targetContent)
|
|
|
|
targetContent->HandleDOMEvent(aPresContext, &mouseOutEvent, nsnull,
|
|
|
|
NS_EVENT_FLAG_INIT, &mouseoutStatus);
|
|
|
|
|
2000-12-09 07:28:19 +00:00
|
|
|
if (scrollPage)
|
|
|
|
sv->ScrollByPages((numLines > 0) ? 1 : -1);
|
|
|
|
else
|
|
|
|
sv->ScrollByLines(0, numLines);
|
|
|
|
|
|
|
|
if (focusView)
|
|
|
|
ForceViewUpdate(focusView);
|
|
|
|
} else {
|
|
|
|
nsresult rv;
|
|
|
|
nsIFrame* newFrame = nsnull;
|
|
|
|
nsCOMPtr<nsIPresContext> newPresContext;
|
|
|
|
|
|
|
|
rv = GetParentScrollingView(msEvent, aPresContext, newFrame,
|
|
|
|
*getter_AddRefs(newPresContext));
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return DoWheelScroll(newPresContext, newFrame, msEvent, numLines,
|
|
|
|
scrollPage, PR_TRUE);
|
|
|
|
else
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsEventStateManager::GetParentScrollingView(nsMouseScrollEvent *aEvent,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* &targetOuterFrame,
|
|
|
|
nsIPresContext* &presCtxOuter)
|
|
|
|
{
|
|
|
|
if (!aEvent) return NS_ERROR_FAILURE;
|
|
|
|
if (!aPresContext) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> shell;
|
|
|
|
aPresContext->GetContainer(getter_AddRefs(shell));
|
|
|
|
if (!shell) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(shell);
|
|
|
|
if (!treeItem) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parent;
|
|
|
|
treeItem->GetParent(getter_AddRefs(parent));
|
|
|
|
if (!parent) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> pDocShell = do_QueryInterface(parent);
|
|
|
|
if (!pDocShell) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
pDocShell->GetPresShell(getter_AddRefs(presShell));
|
|
|
|
if (!presShell) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsIFrame* rootFrame = nsnull;
|
|
|
|
presShell->GetRootFrame(&rootFrame);
|
|
|
|
if (!rootFrame) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
presShell->GetPresContext(&presCtxOuter); //addrefs
|
2001-02-15 05:07:46 +00:00
|
|
|
|
2000-12-09 07:28:19 +00:00
|
|
|
nsPoint eventPoint;
|
|
|
|
rootFrame->GetOrigin(eventPoint);
|
|
|
|
eventPoint += aEvent->point;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
rv = rootFrame->GetFrameForPoint(presCtxOuter, eventPoint,
|
|
|
|
NS_FRAME_PAINT_LAYER_FOREGROUND,
|
|
|
|
&targetOuterFrame);
|
|
|
|
if (rv != NS_OK) {
|
|
|
|
rv = rootFrame->GetFrameForPoint(presCtxOuter, eventPoint,
|
|
|
|
NS_FRAME_PAINT_LAYER_FLOATERS,
|
|
|
|
&targetOuterFrame);
|
|
|
|
if (rv != NS_OK) {
|
|
|
|
rv = rootFrame->GetFrameForPoint(presCtxOuter, eventPoint,
|
|
|
|
NS_FRAME_PAINT_LAYER_BACKGROUND,
|
|
|
|
&targetOuterFrame);
|
|
|
|
if (rv != NS_OK) return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
2001-02-15 05:07:46 +00:00
|
|
|
|
2000-12-09 07:28:19 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
NS_IMETHODIMP
|
2001-02-15 05:07:46 +00:00
|
|
|
nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
|
2000-04-24 04:41:27 +00:00
|
|
|
nsEvent *aEvent,
|
1999-09-16 14:54:59 +00:00
|
|
|
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;
|
2001-02-15 05:07:46 +00:00
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
1998-11-24 07:46:58 +00:00
|
|
|
nsresult ret = NS_OK;
|
|
|
|
|
2000-05-05 14:43:20 +00:00
|
|
|
NS_ASSERTION(mCurrentTarget, "mCurrentTarget is null");
|
|
|
|
if (!mCurrentTarget) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1998-11-24 07:46:58 +00:00
|
|
|
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-12-18 04:02:28 +00:00
|
|
|
if (mConsumeFocusEvents) {
|
|
|
|
mConsumeFocusEvents = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
if (nsEventStatus_eConsumeNoDefault != *aStatus) {
|
1999-09-30 11:40:42 +00:00
|
|
|
nsCOMPtr<nsIContent> newFocus;
|
2000-04-04 23:55:31 +00:00
|
|
|
PRBool suppressBlur = PR_FALSE;
|
|
|
|
if (mCurrentTarget) {
|
|
|
|
mCurrentTarget->GetContentForEvent(mPresContext, aEvent, getter_AddRefs(newFocus));
|
|
|
|
const nsStyleUserInterface* ui;
|
2000-08-08 23:48:42 +00:00
|
|
|
mCurrentTarget->GetStyleData(eStyleStruct_UserInterface, ((const nsStyleStruct*&)ui));
|
2000-04-04 23:55:31 +00:00
|
|
|
suppressBlur = (ui->mUserFocus == NS_STYLE_USER_FOCUS_IGNORE);
|
|
|
|
}
|
1999-08-24 00:42:38 +00:00
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
nsIFrame* currFrame = mCurrentTarget;
|
2000-09-19 01:24:44 +00:00
|
|
|
nsCOMPtr<nsIContent> activeContent;
|
|
|
|
if (mCurrentTarget)
|
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(activeContent));
|
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
// Look for the nearest enclosing focusable frame.
|
|
|
|
while (currFrame) {
|
|
|
|
const nsStyleUserInterface* ui;
|
2000-08-08 23:48:42 +00:00
|
|
|
currFrame->GetStyleData(eStyleStruct_UserInterface, ((const nsStyleStruct*&)ui));
|
2000-04-04 23:55:31 +00:00
|
|
|
if ((ui->mUserFocus != NS_STYLE_USER_FOCUS_IGNORE) &&
|
|
|
|
(ui->mUserFocus != NS_STYLE_USER_FOCUS_NONE)) {
|
|
|
|
currFrame->GetContent(getter_AddRefs(newFocus));
|
2000-05-11 04:25:43 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(newFocus));
|
|
|
|
if (domElement)
|
|
|
|
break;
|
1999-08-24 00:42:38 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
currFrame->GetParent(&currFrame);
|
|
|
|
}
|
1999-09-30 11:40:42 +00:00
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
if (newFocus && currFrame)
|
|
|
|
ChangeFocus(newFocus, currFrame, PR_TRUE);
|
2001-05-22 23:52:17 +00:00
|
|
|
else if (!suppressBlur) {
|
2000-04-04 23:55:31 +00:00
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
2001-05-22 23:52:17 +00:00
|
|
|
}
|
1999-09-30 11:40:42 +00:00
|
|
|
|
2000-09-19 07:25:45 +00:00
|
|
|
if (activeContent) {
|
|
|
|
// The nearest enclosing element goes into the
|
|
|
|
// :active state. If we fail the QI to DOMElement,
|
|
|
|
// then we know we're only a node, and that we need
|
|
|
|
// to obtain our parent element and put it into :active
|
|
|
|
// instead.
|
|
|
|
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(activeContent));
|
|
|
|
if (!elt) {
|
|
|
|
nsCOMPtr<nsIContent> par;
|
|
|
|
activeContent->GetParent(*getter_AddRefs(par));
|
|
|
|
activeContent = par;
|
|
|
|
}
|
2001-05-22 23:52:17 +00:00
|
|
|
if (activeContent) {
|
2000-09-19 07:25:45 +00:00
|
|
|
SetContentState(activeContent, NS_EVENT_STATE_ACTIVE);
|
2001-05-22 23:52:17 +00:00
|
|
|
nsCOMPtr<nsIDOMHTMLBodyElement> bodyElement(do_QueryInterface(activeContent));
|
|
|
|
if (bodyElement) {
|
|
|
|
mSpecialTopOfDoc = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
2000-09-19 07:25:45 +00:00
|
|
|
}
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
2000-09-13 01:45:23 +00:00
|
|
|
else {
|
|
|
|
// if we're here, the event handler returned false, so stop
|
|
|
|
// any of our own processing of a drag. Workaround for bug 43258.
|
|
|
|
StopTrackingDragGesture();
|
|
|
|
}
|
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
|
|
|
{
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_ACTIVE);
|
2001-04-05 19:53:13 +00:00
|
|
|
ret = CheckForAndDispatchClick(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
1999-05-07 21:12:59 +00:00
|
|
|
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) {
|
2000-03-15 04:03:44 +00:00
|
|
|
nsresult rv;
|
|
|
|
rv = getPrefService();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-06 06:22:00 +00:00
|
|
|
nsMouseScrollEvent *msEvent = (nsMouseScrollEvent*) aEvent;
|
|
|
|
PRInt32 action = 0;
|
|
|
|
PRInt32 numLines = 0;
|
2000-11-02 05:15:34 +00:00
|
|
|
PRBool aBool;
|
2000-01-06 06:22:00 +00:00
|
|
|
if (msEvent->isShift) {
|
2000-03-15 04:03:44 +00:00
|
|
|
mPrefService->GetIntPref("mousewheel.withshiftkey.action", &action);
|
2000-11-02 05:15:34 +00:00
|
|
|
mPrefService->GetBoolPref("mousewheel.withshiftkey.sysnumlines",
|
|
|
|
&aBool);
|
|
|
|
if (aBool) {
|
|
|
|
numLines = msEvent->delta;
|
2000-11-13 18:16:43 +00:00
|
|
|
if (msEvent->scrollFlags & nsMouseScrollEvent::kIsFullPage)
|
2000-11-02 05:15:34 +00:00
|
|
|
action = MOUSE_SCROLL_PAGE;
|
|
|
|
}
|
2000-01-06 06:22:00 +00:00
|
|
|
else
|
2000-11-02 05:15:34 +00:00
|
|
|
mPrefService->GetIntPref("mousewheel.withshiftkey.numlines",
|
|
|
|
&numLines);
|
2000-01-06 06:22:00 +00:00
|
|
|
} else if (msEvent->isControl) {
|
2000-03-15 04:03:44 +00:00
|
|
|
mPrefService->GetIntPref("mousewheel.withcontrolkey.action", &action);
|
2000-11-02 05:15:34 +00:00
|
|
|
mPrefService->GetBoolPref("mousewheel.withcontrolkey.sysnumlines",
|
|
|
|
&aBool);
|
|
|
|
if (aBool) {
|
|
|
|
numLines = msEvent->delta;
|
2000-11-13 18:16:43 +00:00
|
|
|
if (msEvent->scrollFlags & nsMouseScrollEvent::kIsFullPage)
|
2000-11-02 05:15:34 +00:00
|
|
|
action = MOUSE_SCROLL_PAGE;
|
|
|
|
}
|
2000-01-06 06:22:00 +00:00
|
|
|
else
|
2000-11-02 05:15:34 +00:00
|
|
|
mPrefService->GetIntPref("mousewheel.withcontrolkey.numlines",
|
|
|
|
&numLines);
|
2000-01-06 06:22:00 +00:00
|
|
|
} else if (msEvent->isAlt) {
|
2000-03-15 04:03:44 +00:00
|
|
|
mPrefService->GetIntPref("mousewheel.withaltkey.action", &action);
|
|
|
|
mPrefService->GetBoolPref("mousewheel.withaltkey.sysnumlines", &aBool);
|
2000-11-02 05:15:34 +00:00
|
|
|
if (aBool) {
|
|
|
|
numLines = msEvent->delta;
|
2000-11-13 18:16:43 +00:00
|
|
|
if (msEvent->scrollFlags & nsMouseScrollEvent::kIsFullPage)
|
2000-11-02 05:15:34 +00:00
|
|
|
action = MOUSE_SCROLL_PAGE;
|
|
|
|
}
|
2000-01-06 06:22:00 +00:00
|
|
|
else
|
2000-11-02 05:15:34 +00:00
|
|
|
mPrefService->GetIntPref("mousewheel.withaltkey.numlines",
|
|
|
|
&numLines);
|
2000-01-06 06:22:00 +00:00
|
|
|
} else {
|
2000-03-15 04:03:44 +00:00
|
|
|
mPrefService->GetIntPref("mousewheel.withnokey.action", &action);
|
|
|
|
mPrefService->GetBoolPref("mousewheel.withnokey.sysnumlines", &aBool);
|
2000-11-02 05:15:34 +00:00
|
|
|
if (aBool) {
|
|
|
|
numLines = msEvent->delta;
|
2000-11-13 18:16:43 +00:00
|
|
|
if (msEvent->scrollFlags & nsMouseScrollEvent::kIsFullPage)
|
2000-11-02 05:15:34 +00:00
|
|
|
action = MOUSE_SCROLL_PAGE;
|
|
|
|
}
|
2000-01-06 06:22:00 +00:00
|
|
|
else
|
2000-03-15 04:03:44 +00:00
|
|
|
mPrefService->GetIntPref("mousewheel.withnokey.numlines", &numLines);
|
2000-01-06 06:22:00 +00:00
|
|
|
}
|
1999-11-21 01:46:41 +00:00
|
|
|
|
2000-11-02 05:15:34 +00:00
|
|
|
if ((msEvent->delta < 0) && (numLines > 0))
|
2000-01-06 06:22:00 +00:00
|
|
|
numLines = -numLines;
|
1999-11-21 01:46:41 +00:00
|
|
|
|
2000-01-06 06:22:00 +00:00
|
|
|
switch (action) {
|
|
|
|
case MOUSE_SCROLL_N_LINES:
|
2000-05-15 02:10:11 +00:00
|
|
|
case MOUSE_SCROLL_PAGE:
|
2000-01-06 06:22:00 +00:00
|
|
|
{
|
2001-02-19 12:55:42 +00:00
|
|
|
DoWheelScroll(aPresContext, aTargetFrame, msEvent, numLines,
|
|
|
|
(action == MOUSE_SCROLL_PAGE), PR_FALSE);
|
2000-06-28 20:35:32 +00:00
|
|
|
|
2000-01-06 06:22:00 +00:00
|
|
|
}
|
2000-04-01 20:09:54 +00:00
|
|
|
|
2000-01-16 05:30:49 +00:00
|
|
|
break;
|
|
|
|
|
2000-01-06 06:22:00 +00:00
|
|
|
case MOUSE_SCROLL_HISTORY:
|
|
|
|
{
|
2000-03-12 01:19:39 +00:00
|
|
|
nsCOMPtr<nsISupports> pcContainer;
|
|
|
|
mPresContext->GetContainer(getter_AddRefs(pcContainer));
|
|
|
|
if (pcContainer) {
|
2000-04-16 06:14:38 +00:00
|
|
|
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(pcContainer));
|
|
|
|
if (webNav) {
|
2000-11-02 05:15:34 +00:00
|
|
|
if (msEvent->delta > 0)
|
2000-04-16 06:14:38 +00:00
|
|
|
webNav->GoBack();
|
|
|
|
else
|
|
|
|
webNav->GoForward();
|
2000-03-12 01:19:39 +00:00
|
|
|
}
|
2000-01-06 06:22:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2000-02-17 23:52:45 +00:00
|
|
|
|
2000-04-25 06:25:43 +00:00
|
|
|
case MOUSE_SCROLL_TEXTSIZE:
|
2000-11-02 05:15:34 +00:00
|
|
|
ChangeTextSize((msEvent->delta > 0) ? 1 : -1);
|
2000-04-25 06:25:43 +00:00
|
|
|
break;
|
1999-11-21 01:46:41 +00:00
|
|
|
}
|
2000-02-17 23:52:45 +00:00
|
|
|
*aStatus = nsEventStatus_eConsumeNoDefault;
|
|
|
|
|
1999-11-21 01:46:41 +00:00
|
|
|
}
|
1999-12-28 23:02:38 +00:00
|
|
|
|
2000-01-06 06:22:00 +00:00
|
|
|
break;
|
2001-02-15 05:07:46 +00:00
|
|
|
|
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!
|
2000-04-24 04:41:27 +00:00
|
|
|
GenerateDragDropEnterExit(aPresContext, (nsGUIEvent*)aEvent);
|
1999-11-12 01:02:14 +00:00
|
|
|
break;
|
2001-02-15 05:07:46 +00:00
|
|
|
|
|
|
|
case NS_KEY_UP:
|
|
|
|
if (mBrowseWithCaret)
|
|
|
|
MoveFocusToCaret();
|
|
|
|
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:
|
2001-05-22 23:52:17 +00:00
|
|
|
if (mConsumeFocusEvents) {
|
|
|
|
mConsumeFocusEvents = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!((nsInputEvent*)aEvent)->isControl) {
|
|
|
|
//Shift focus forward or back depending on shift key
|
|
|
|
ShiftFocus(!((nsInputEvent*)aEvent)->isShift);
|
|
|
|
} else {
|
|
|
|
ShiftFocusByDoc(!((nsInputEvent*)aEvent)->isShift);
|
|
|
|
}
|
|
|
|
*aStatus = nsEventStatus_eConsumeNoDefault;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_VK_F6:
|
1999-12-21 19:35:13 +00:00
|
|
|
if (mConsumeFocusEvents) {
|
|
|
|
mConsumeFocusEvents = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
1999-11-22 19:45:13 +00:00
|
|
|
//Shift focus forward or back depending on shift key
|
2001-05-22 23:52:17 +00:00
|
|
|
ShiftFocusByDoc(!((nsInputEvent*)aEvent)->isShift);
|
1999-11-24 06:03:41 +00:00
|
|
|
*aStatus = nsEventStatus_eConsumeNoDefault;
|
1999-11-22 19:45:13 +00:00
|
|
|
break;
|
1999-12-11 00:02:08 +00:00
|
|
|
|
2001-02-15 05:07:46 +00:00
|
|
|
//the problem is that viewer does not have xul so we cannot completely eliminate these
|
1999-12-11 00:02:08 +00:00
|
|
|
#if NON_KEYBINDING
|
2001-02-15 05:07:46 +00:00
|
|
|
case NS_VK_PAGE_DOWN:
|
1999-11-22 19:45:13 +00:00
|
|
|
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;
|
2000-05-16 11:35:12 +00:00
|
|
|
sv->ScrollByLines(0, (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();
|
|
|
|
vm->ForceUpdate();
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NS_VK_LEFT:
|
|
|
|
case NS_VK_RIGHT:
|
|
|
|
if (!mCurrentFocus) {
|
|
|
|
nsIScrollableView* sv = GetNearestScrollingView(aView);
|
|
|
|
if (sv) {
|
|
|
|
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
|
|
|
sv->ScrollByLines((keyEvent->keyCode == NS_VK_RIGHT) ? 1 : -1, 0);
|
1999-11-22 19:45:13 +00:00
|
|
|
|
|
|
|
// 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();
|
2000-01-26 23:04:40 +00:00
|
|
|
vm->ForceUpdate();
|
1999-11-22 19:45:13 +00:00
|
|
|
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-12-11 00:02:08 +00:00
|
|
|
#endif //NON_KEYBINDING
|
1999-07-06 22:55:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-01-06 05:58:47 +00:00
|
|
|
case NS_MOUSE_ENTER:
|
|
|
|
nsCOMPtr<nsIContent> targetContent;
|
|
|
|
if (mCurrentTarget) {
|
|
|
|
mCurrentTarget->GetContentForEvent(aPresContext, aEvent,
|
|
|
|
getter_AddRefs(targetContent));
|
|
|
|
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
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
|
|
|
{
|
1999-12-08 20:18:16 +00:00
|
|
|
if (aPresContext == nsnull) {
|
|
|
|
// A pres context is going away. Make sure we do cleanup.
|
|
|
|
if (mPresContext == gLastFocusedPresContext) {
|
|
|
|
gLastFocusedPresContext = nsnull;
|
|
|
|
NS_IF_RELEASE(gLastFocusedDocument);
|
1999-12-11 05:42:18 +00:00
|
|
|
NS_IF_RELEASE(gLastFocusedContent);
|
1999-12-08 20:18:16 +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;
|
2001-03-30 04:45:40 +00:00
|
|
|
if (aFrame == mGestureDownFrame) {
|
1999-11-02 03:55:14 +00:00
|
|
|
mGestureDownFrame = nsnull;
|
2001-03-30 04:45:40 +00:00
|
|
|
#if CLICK_HOLD_CONTEXT_MENUS
|
|
|
|
mEventDownWidget = nsnull;
|
|
|
|
mEventPresContext = nsnull;
|
|
|
|
#endif
|
|
|
|
}
|
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;
|
|
|
|
}
|
2001-03-30 04:45:40 +00:00
|
|
|
|
|
|
|
|
1998-11-19 00:43:36 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-30 19:38:39 +00:00
|
|
|
nsIScrollableView*
|
|
|
|
nsEventStateManager::GetNearestScrollingView(nsIView* aView)
|
|
|
|
{
|
|
|
|
nsIScrollableView* sv;
|
2000-02-05 00:58:29 +00:00
|
|
|
if (NS_OK == aView->QueryInterface(NS_GET_IID(nsIScrollableView),
|
|
|
|
(void**)&sv)) {
|
1999-04-30 19:38:39 +00:00
|
|
|
return sv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIView* parent;
|
|
|
|
aView->GetParent(parent);
|
|
|
|
|
|
|
|
if (nsnull != parent) {
|
|
|
|
return GetNearestScrollingView(parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
1999-12-04 02:22:21 +00:00
|
|
|
PRBool
|
|
|
|
nsEventStateManager::CheckDisabled(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
PRBool disabled = PR_FALSE;
|
|
|
|
|
2000-01-12 06:54:58 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
1999-12-04 02:22:21 +00:00
|
|
|
|
2000-01-12 07:39:00 +00:00
|
|
|
if (nsHTMLAtoms::input == tag.get() ||
|
|
|
|
nsHTMLAtoms::select == tag.get() ||
|
|
|
|
nsHTMLAtoms::textarea == tag.get() ||
|
|
|
|
nsHTMLAtoms::button == tag.get()) {
|
1999-12-04 02:22:21 +00:00
|
|
|
nsAutoString empty;
|
|
|
|
if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML,
|
|
|
|
nsHTMLAtoms::disabled,
|
|
|
|
empty)) {
|
|
|
|
disabled = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return disabled;
|
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
void
|
2000-02-11 01:24:59 +00:00
|
|
|
nsEventStateManager::UpdateCursor(nsIPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame,
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStatus* aStatus)
|
1998-07-17 04:52:12 +00:00
|
|
|
{
|
1998-11-18 05:25:26 +00:00
|
|
|
PRInt32 cursor;
|
1999-12-04 02:22:21 +00:00
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
//If cursor is locked just use the locked one
|
|
|
|
if (mLockCursor) {
|
|
|
|
cursor = mLockCursor;
|
1999-12-04 02:22:21 +00:00
|
|
|
}
|
2000-04-24 04:41:27 +00:00
|
|
|
//If not locked, look for correct cursor
|
|
|
|
else {
|
|
|
|
nsCOMPtr<nsIContent> targetContent;
|
|
|
|
if (mCurrentTarget) {
|
|
|
|
mCurrentTarget->GetContent(getter_AddRefs(targetContent));
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
//Check if the current target is disabled. If so use the default pointer.
|
|
|
|
if (targetContent && CheckDisabled(targetContent)) {
|
|
|
|
cursor = NS_STYLE_CURSOR_DEFAULT;
|
|
|
|
}
|
|
|
|
//If not disabled, check for the right cursor.
|
|
|
|
else {
|
|
|
|
if (aTargetFrame) {
|
|
|
|
aTargetFrame->GetCursor(aPresContext, aEvent->point, cursor);
|
|
|
|
}
|
|
|
|
}
|
1999-12-04 02:22:21 +00:00
|
|
|
}
|
2000-04-24 04:41:27 +00:00
|
|
|
|
2001-01-26 12:35:32 +00:00
|
|
|
// Check whether or not to show the busy cursor
|
|
|
|
nsCOMPtr<nsISupports> pcContainer;
|
|
|
|
aPresContext->GetContainer(getter_AddRefs(pcContainer));
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(pcContainer));
|
2001-03-19 23:01:59 +00:00
|
|
|
if (!docShell) return;
|
2001-01-26 12:35:32 +00:00
|
|
|
PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
|
|
|
|
docShell->GetBusyFlags(&busyFlags);
|
|
|
|
|
|
|
|
// Show busy cursor everywhere before page loads
|
|
|
|
// and just replace the arrow cursor after page starts loading
|
|
|
|
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY &&
|
|
|
|
(cursor == NS_STYLE_CURSOR_AUTO || cursor == NS_STYLE_CURSOR_DEFAULT))
|
|
|
|
{
|
|
|
|
cursor = NS_STYLE_CURSOR_SPINNING;
|
|
|
|
}
|
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
if (aTargetFrame) {
|
|
|
|
nsCOMPtr<nsIWidget> window;
|
|
|
|
aTargetFrame->GetWindow(aPresContext, getter_AddRefs(window));
|
|
|
|
SetCursor(cursor, window, PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mLockCursor || NS_STYLE_CURSOR_AUTO != cursor) {
|
|
|
|
*aStatus = nsEventStatus_eConsumeDoDefault;
|
1999-12-04 02:22:21 +00:00
|
|
|
}
|
2000-04-24 04:41:27 +00:00
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::SetCursor(PRInt32 aCursor, nsIWidget* aWidget, PRBool aLockCursor)
|
|
|
|
{
|
|
|
|
nsCursor c;
|
|
|
|
|
|
|
|
NS_ENSURE_TRUE(aWidget, NS_ERROR_FAILURE);
|
|
|
|
if (aLockCursor) {
|
|
|
|
if (NS_STYLE_CURSOR_AUTO != aCursor) {
|
|
|
|
mLockCursor = aCursor;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
//If cursor style is set to auto we unlock the cursor again.
|
|
|
|
mLockCursor = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (aCursor) {
|
1998-11-18 05:25:26 +00:00
|
|
|
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;
|
|
|
|
case NS_STYLE_CURSOR_NW_RESIZE:
|
2000-04-30 15:29:32 +00:00
|
|
|
c = eCursor_sizeNW;
|
|
|
|
break;
|
1998-11-18 05:25:26 +00:00
|
|
|
case NS_STYLE_CURSOR_SE_RESIZE:
|
2000-04-30 15:29:32 +00:00
|
|
|
c = eCursor_sizeSE;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_NE_RESIZE:
|
|
|
|
c = eCursor_sizeNE;
|
|
|
|
break;
|
1998-11-18 05:25:26 +00:00
|
|
|
case NS_STYLE_CURSOR_SW_RESIZE:
|
2000-04-30 15:29:32 +00:00
|
|
|
c = eCursor_sizeSW;
|
1998-11-18 05:25:26 +00:00
|
|
|
break;
|
2000-05-07 05:14:43 +00:00
|
|
|
case NS_STYLE_CURSOR_COPY: // CSS3
|
|
|
|
c = eCursor_copy;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_ALIAS:
|
|
|
|
c = eCursor_alias;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_CONTEXT_MENU:
|
|
|
|
c = eCursor_context_menu;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_CELL:
|
|
|
|
c = eCursor_cell;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_GRAB:
|
|
|
|
c = eCursor_grab;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_GRABBING:
|
|
|
|
c = eCursor_grabbing;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_SPINNING:
|
|
|
|
c = eCursor_spinning;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_COUNT_UP:
|
|
|
|
c = eCursor_count_up;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_COUNT_DOWN:
|
|
|
|
c = eCursor_count_down;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_CURSOR_COUNT_UP_DOWN:
|
|
|
|
c = eCursor_count_up_down;
|
|
|
|
break;
|
1998-07-17 04:52:12 +00:00
|
|
|
}
|
1998-12-03 03:07:16 +00:00
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
aWidget->SetCursor(c);
|
1998-12-03 03:07:16 +00:00
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
return NS_OK;
|
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:
|
|
|
|
{
|
2000-02-11 01:24:59 +00:00
|
|
|
nsCOMPtr<nsIContent> targetContent;
|
|
|
|
if (mCurrentTarget) {
|
|
|
|
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(targetContent));
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2000-02-11 01:24:59 +00:00
|
|
|
if (mLastMouseOverContent.get() != targetContent.get()) {
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2000-02-16 03:52:45 +00:00
|
|
|
//Before firing mouseout, check for recursion
|
|
|
|
if (mLastMouseOverContent.get() != mFirstMouseOutEventContent.get()) {
|
|
|
|
|
|
|
|
//Store the first mouseOut event we fire and don't refire mouseOut
|
|
|
|
//to that element while the first mouseOut is still ongoing.
|
|
|
|
mFirstMouseOutEventContent = mLastMouseOverContent;
|
|
|
|
|
|
|
|
if (mLastMouseOverFrame) {
|
|
|
|
//fire mouseout
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_MOUSE_EVENT;
|
2000-04-24 04:41:27 +00:00
|
|
|
event.message = NS_MOUSE_EXIT_SYNTH;
|
2000-02-16 03:52:45 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
|
|
|
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
|
|
|
|
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
|
|
|
|
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
|
|
|
|
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
|
2001-01-28 01:36:21 +00:00
|
|
|
event.nativeMsg = ((nsMouseEvent*)aEvent)->nativeMsg;
|
2000-02-16 03:52:45 +00:00
|
|
|
|
|
|
|
mCurrentTargetContent = mLastMouseOverContent;
|
|
|
|
NS_IF_ADDREF(mCurrentTargetContent);
|
|
|
|
mCurrentRelatedContent = targetContent;
|
|
|
|
NS_IF_ADDREF(mCurrentRelatedContent);
|
|
|
|
|
|
|
|
//XXX This event should still go somewhere!!
|
|
|
|
if (mLastMouseOverContent) {
|
|
|
|
mLastMouseOverContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Now dispatch to the frame
|
|
|
|
if (mLastMouseOverFrame) {
|
|
|
|
//XXX Get the new frame
|
|
|
|
mLastMouseOverFrame->HandleEvent(aPresContext, &event, &status);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
|
|
|
NS_IF_RELEASE(mCurrentRelatedContent);
|
|
|
|
|
|
|
|
mFirstMouseOutEventContent = nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Before firing mouseover, check for recursion
|
|
|
|
if (targetContent.get() != mFirstMouseOverEventContent.get()) {
|
|
|
|
|
|
|
|
//Store the first mouseOver event we fire and don't refire mouseOver
|
|
|
|
//to that element while the first mouseOver is still ongoing.
|
|
|
|
mFirstMouseOverEventContent = targetContent;
|
|
|
|
|
|
|
|
//fire mouseover
|
1998-11-18 05:25:26 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_MOUSE_EVENT;
|
2000-04-24 04:41:27 +00:00
|
|
|
event.message = NS_MOUSE_ENTER_SYNTH;
|
1999-07-01 04:12:42 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1999-12-09 21:02:09 +00:00
|
|
|
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
|
|
|
|
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
|
|
|
|
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
|
|
|
|
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
|
2001-01-28 01:36:21 +00:00
|
|
|
event.nativeMsg = ((nsMouseEvent*)aEvent)->nativeMsg;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2000-02-16 03:52:45 +00:00
|
|
|
mCurrentTargetContent = targetContent;
|
1999-11-03 07:11:45 +00:00
|
|
|
NS_IF_ADDREF(mCurrentTargetContent);
|
2000-02-16 03:52:45 +00:00
|
|
|
mCurrentRelatedContent = mLastMouseOverContent;
|
1999-11-03 07:11:45 +00:00
|
|
|
NS_IF_ADDREF(mCurrentRelatedContent);
|
|
|
|
|
2000-02-11 01:24:59 +00:00
|
|
|
//XXX This event should still go somewhere!!
|
2000-02-16 03:52:45 +00:00
|
|
|
if (targetContent) {
|
|
|
|
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
|
|
|
|
2000-10-16 21:52:22 +00:00
|
|
|
if ( status != nsEventStatus_eConsumeNoDefault )
|
2000-02-16 03:52:45 +00:00
|
|
|
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
|
2000-10-16 21:52:22 +00:00
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
//Now dispatch to the frame
|
2000-02-16 03:52:45 +00:00
|
|
|
if (mCurrentTarget) {
|
1999-01-28 23:14:36 +00:00
|
|
|
//XXX Get the new frame
|
2000-02-16 03:52:45 +00:00
|
|
|
mCurrentTarget->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);
|
2000-02-16 03:52:45 +00:00
|
|
|
mLastMouseOverFrame = mCurrentTarget;
|
|
|
|
mLastMouseOverContent = targetContent;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2000-02-16 03:52:45 +00:00
|
|
|
mFirstMouseOverEventContent = nsnull;
|
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) {
|
2000-02-16 03:52:45 +00:00
|
|
|
//Before firing mouseout, check for recursion
|
|
|
|
if (mLastMouseOverContent.get() != mFirstMouseOutEventContent.get()) {
|
|
|
|
|
|
|
|
//Store the first mouseOut event we fire and don't refire mouseOut
|
|
|
|
//to that element while the first mouseOut is still ongoing.
|
|
|
|
mFirstMouseOutEventContent = mLastMouseOverContent;
|
1999-06-22 14:20:14 +00:00
|
|
|
|
2000-02-16 03:52:45 +00:00
|
|
|
//fire mouseout
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsMouseEvent event;
|
|
|
|
event.eventStructType = NS_MOUSE_EVENT;
|
2000-04-24 04:41:27 +00:00
|
|
|
event.message = NS_MOUSE_EXIT_SYNTH;
|
2000-02-16 03:52:45 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
|
|
|
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
|
|
|
|
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
|
|
|
|
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
|
|
|
|
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
|
2001-01-28 01:36:21 +00:00
|
|
|
event.nativeMsg = ((nsMouseEvent*)aEvent)->nativeMsg;
|
2000-02-16 03:52:45 +00:00
|
|
|
|
|
|
|
mCurrentTargetContent = mLastMouseOverContent;
|
|
|
|
NS_IF_ADDREF(mCurrentTargetContent);
|
|
|
|
mCurrentRelatedContent = nsnull;
|
|
|
|
|
|
|
|
if (mLastMouseOverContent) {
|
|
|
|
mLastMouseOverContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
|
2000-10-10 20:48:03 +00:00
|
|
|
if ( status != nsEventStatus_eConsumeNoDefault )
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_HOVER);
|
1999-06-22 14:20:14 +00:00
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2000-02-16 03:52:45 +00:00
|
|
|
//Now dispatch to the frame
|
|
|
|
if (nsnull != mLastMouseOverFrame) {
|
|
|
|
//XXX Get the new frame
|
|
|
|
mLastMouseOverFrame->HandleEvent(aPresContext, &event, &status);
|
|
|
|
mLastMouseOverFrame = nsnull;
|
|
|
|
mLastMouseOverContent = nsnull;
|
|
|
|
}
|
1999-11-03 07:11:45 +00:00
|
|
|
|
2000-02-16 03:52:45 +00:00
|
|
|
NS_IF_RELEASE(mCurrentTargetContent);
|
|
|
|
|
|
|
|
mFirstMouseOutEventContent = nsnull;
|
|
|
|
}
|
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;
|
2000-02-11 01:24:59 +00:00
|
|
|
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, 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;
|
2000-04-24 04:41:27 +00:00
|
|
|
event.message = NS_DRAGDROP_EXIT_SYNTH;
|
1999-07-01 04:12:42 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1999-12-09 21:02:09 +00:00
|
|
|
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
|
|
|
|
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
|
|
|
|
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
|
|
|
|
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
|
1999-05-04 14:44:51 +00:00
|
|
|
|
|
|
|
//The frame has change but the content may not have. Check before dispatching to content
|
2000-02-11 01:24:59 +00:00
|
|
|
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, 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-12-09 21:02:09 +00:00
|
|
|
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
|
|
|
|
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
|
|
|
|
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
|
|
|
|
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
|
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;
|
2000-04-24 04:41:27 +00:00
|
|
|
event.message = NS_DRAGDROP_EXIT_SYNTH;
|
1999-07-01 04:12:42 +00:00
|
|
|
event.widget = aEvent->widget;
|
|
|
|
event.clickCount = 0;
|
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1999-12-09 21:02:09 +00:00
|
|
|
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
|
|
|
|
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
|
|
|
|
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
|
|
|
|
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
|
1999-05-04 14:44:51 +00:00
|
|
|
|
1999-11-02 03:55:14 +00:00
|
|
|
// dispatch to content via DOM
|
|
|
|
nsCOMPtr<nsIContent> lastContent;
|
2000-02-11 01:24:59 +00:00
|
|
|
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, 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;
|
2000-10-16 21:52:22 +00:00
|
|
|
|
|
|
|
// Now flush all pending notifications.
|
2001-01-20 04:59:39 +00:00
|
|
|
FlushPendingEvents(aPresContext);
|
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
|
|
|
|
2000-02-11 01:24:59 +00:00
|
|
|
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, 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;
|
|
|
|
|
2000-02-11 01:24:59 +00:00
|
|
|
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(mouseContent));
|
1999-09-22 02:29:33 +00:00
|
|
|
|
|
|
|
//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;
|
2000-01-15 17:21:20 +00:00
|
|
|
event.point = aEvent->point;
|
|
|
|
event.refPoint = aEvent->refPoint;
|
1999-09-22 02:29:33 +00:00
|
|
|
event.clickCount = aEvent->clickCount;
|
1999-12-09 21:02:09 +00:00
|
|
|
event.isShift = aEvent->isShift;
|
|
|
|
event.isControl = aEvent->isControl;
|
|
|
|
event.isAlt = aEvent->isAlt;
|
|
|
|
event.isMeta = aEvent->isMeta;
|
1998-11-24 07:46:58 +00:00
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
mPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
if (presShell) {
|
2000-09-19 21:47:04 +00:00
|
|
|
ret = presShell->HandleEventWithTarget(&event, mCurrentTarget, mouseContent, NS_EVENT_FLAG_INIT, aStatus);
|
2000-08-08 20:32:09 +00:00
|
|
|
if (NS_SUCCEEDED(ret) && aEvent->clickCount == 2) {
|
|
|
|
nsMouseEvent event2;
|
|
|
|
//fire double click
|
|
|
|
switch (aEvent->message) {
|
|
|
|
case NS_MOUSE_LEFT_BUTTON_UP:
|
|
|
|
event2.message = NS_MOUSE_LEFT_DOUBLECLICK;
|
|
|
|
break;
|
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
|
|
|
event2.message = NS_MOUSE_MIDDLE_DOUBLECLICK;
|
|
|
|
break;
|
|
|
|
case NS_MOUSE_RIGHT_BUTTON_UP:
|
|
|
|
event2.message = NS_MOUSE_RIGHT_DOUBLECLICK;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
event2.eventStructType = NS_MOUSE_EVENT;
|
|
|
|
event2.widget = aEvent->widget;
|
|
|
|
event2.point = aEvent->point;
|
|
|
|
event2.refPoint = aEvent->refPoint;
|
|
|
|
event2.clickCount = aEvent->clickCount;
|
|
|
|
event2.isShift = aEvent->isShift;
|
|
|
|
event2.isControl = aEvent->isControl;
|
|
|
|
event2.isAlt = aEvent->isAlt;
|
|
|
|
event2.isMeta = aEvent->isMeta;
|
|
|
|
|
2000-09-19 21:47:04 +00:00
|
|
|
ret = presShell->HandleEventWithTarget(&event2, mCurrentTarget, mouseContent, NS_EVENT_FLAG_INIT, aStatus);
|
2000-08-08 20:32:09 +00:00
|
|
|
}
|
1999-04-13 00:27:58 +00:00
|
|
|
}
|
1998-11-24 07:46:58 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
PRBool
|
1999-12-08 04:54:29 +00:00
|
|
|
nsEventStateManager::ChangeFocus(nsIContent* aFocusContent, nsIFrame* aTargetFrame, PRBool aSetFocus)
|
1999-03-02 19:19:24 +00:00
|
|
|
{
|
2000-04-04 23:55:31 +00:00
|
|
|
aFocusContent->SetFocus(mPresContext);
|
2001-02-15 05:07:46 +00:00
|
|
|
MoveCaretToFocus();
|
|
|
|
|
1999-03-02 19:19:24 +00:00
|
|
|
return PR_FALSE;
|
2001-02-15 05:07:46 +00:00
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
|
2001-04-11 03:11:34 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::MoveFocus(PRBool aDirection, nsIContent* aRoot)
|
|
|
|
{
|
|
|
|
ShiftFocus(aDirection, aRoot);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-05-22 23:52:17 +00:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// Debug Helpers
|
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
static void
|
|
|
|
PrintDocTree(nsIDocShellTreeNode * aParentNode, int aLevel)
|
|
|
|
{
|
|
|
|
for (PRInt32 i=0;i<aLevel;i++) printf(" ");
|
|
|
|
|
|
|
|
PRInt32 childWebshellCount;
|
|
|
|
aParentNode->GetChildCount(&childWebshellCount);
|
|
|
|
nsCOMPtr<nsIDocShell> parentAsDocShell(do_QueryInterface(aParentNode));
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(aParentNode));
|
|
|
|
PRInt32 type;
|
|
|
|
parentAsItem->GetItemType(&type);
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
parentAsDocShell->GetPresShell(getter_AddRefs(presShell));
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
parentAsDocShell->GetPresContext(getter_AddRefs(presContext));
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
presShell->GetDocument(getter_AddRefs(doc));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> sgo;
|
|
|
|
doc->GetScriptGlobalObject(getter_AddRefs(sgo));
|
|
|
|
nsCOMPtr<nsIDOMWindowInternal> domwin(do_QueryInterface(sgo));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIWidget> widget;
|
|
|
|
nsCOMPtr<nsIViewManager> vm;
|
|
|
|
presShell->GetViewManager(getter_AddRefs(vm));
|
|
|
|
if (vm) {
|
|
|
|
vm->GetWidget(getter_AddRefs(widget));
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIEventStateManager> esm;
|
|
|
|
presContext->GetEventStateManager(getter_AddRefs(esm));
|
|
|
|
|
|
|
|
printf("DS %p Type %s Cnt %d Doc %p DW %p EM %p\n",
|
|
|
|
parentAsDocShell.get(),
|
|
|
|
type==nsIDocShellTreeItem::typeChrome?"Chrome":"Content",
|
|
|
|
childWebshellCount, doc.get(), domwin.get(), esm.get());
|
|
|
|
|
|
|
|
if (childWebshellCount > 0) {
|
|
|
|
for (PRInt32 i=0;i<childWebshellCount;i++) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> child;
|
|
|
|
aParentNode->GetChildAt(i, getter_AddRefs(child));
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> childAsNode(do_QueryInterface(child));
|
|
|
|
PrintDocTree(childAsNode, aLevel+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
PrintDocTree(nsIDocShellTreeNode * aParentNode)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aParentNode, "Pointer is null!");
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> item(do_QueryInterface(aParentNode));
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentItem;
|
|
|
|
item->GetParent(getter_AddRefs(parentItem));
|
|
|
|
while (parentItem) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem>tmp;
|
|
|
|
parentItem->GetParent(getter_AddRefs(tmp));
|
|
|
|
if (!tmp) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
parentItem = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parentItem) {
|
|
|
|
parentItem = do_QueryInterface(aParentNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parentItem) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(parentItem));
|
|
|
|
PrintDocTree(parentAsNode, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // end debug helpers
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
void
|
2001-04-11 03:11:34 +00:00
|
|
|
nsEventStateManager::ShiftFocus(PRBool forward, nsIContent* aRoot)
|
1998-11-18 05:25:26 +00:00
|
|
|
{
|
2001-05-22 23:52:17 +00:00
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
{
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
mDocument->GetShellAt(0, getter_AddRefs(presShell));
|
2001-05-22 23:52:17 +00:00
|
|
|
if (presShell) {
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
presShell->GetPresContext(getter_AddRefs(presContext));
|
|
|
|
if (presContext) {
|
|
|
|
nsCOMPtr<nsISupports> pcContainer;
|
|
|
|
presContext->GetContainer(getter_AddRefs(pcContainer));
|
|
|
|
if (pcContainer) {
|
|
|
|
nsCOMPtr<nsIDocShell> docshell(do_QueryInterface(pcContainer));
|
|
|
|
printf("ShiftFocus DocShell %p Doc: %p\n", docshell.get(), mDocument);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-04-12 21:24:07 +00:00
|
|
|
PRBool topOfDoc = PR_FALSE;
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
if (nsnull == mPresContext) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-06-28 20:35:32 +00:00
|
|
|
EnsureDocument(mPresContext);
|
2000-04-10 20:52:52 +00:00
|
|
|
if (nsnull == mDocument) {
|
2000-06-28 20:35:32 +00:00
|
|
|
return;
|
2000-04-10 20:52:52 +00:00
|
|
|
}
|
2001-05-22 23:52:17 +00:00
|
|
|
|
|
|
|
// Figure out what type of document we are
|
|
|
|
eDocType docType;
|
|
|
|
FigureOutKindOfDoc(mDocument, &docType);
|
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
printf("Doc Type is [%s]\n", gDocTypeNames[docType]);
|
|
|
|
#endif
|
2000-04-10 20:52:52 +00:00
|
|
|
|
2001-04-11 03:11:34 +00:00
|
|
|
if (aRoot) {
|
|
|
|
NS_IF_RELEASE(mCurrentFocus);
|
|
|
|
mCurrentFocus = aRoot;
|
|
|
|
NS_ADDREF(mCurrentFocus);
|
2001-05-22 23:52:17 +00:00
|
|
|
//mCurrentTabIndex = forward ? 1 : 0;
|
|
|
|
// for frames this needs to be set to 0
|
|
|
|
// otherwise it doesn't look for the next content correctly
|
|
|
|
//if (docType == eFrame) {
|
|
|
|
mCurrentTabIndex = 0;
|
|
|
|
//}
|
2001-04-11 03:11:34 +00:00
|
|
|
}
|
|
|
|
else if (nsnull == mCurrentFocus) {
|
2001-06-20 03:27:48 +00:00
|
|
|
mDocument->GetRootContent(&mCurrentFocus);
|
2001-02-15 05:07:46 +00:00
|
|
|
if (nsnull == mCurrentFocus) {
|
1998-11-18 05:25:26 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2001-02-15 05:07:46 +00:00
|
|
|
nsIFrame* primaryFrame = nsnull;
|
2000-04-04 23:55:31 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
if (mPresContext) {
|
|
|
|
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
if (NS_SUCCEEDED(rv) && shell){
|
2001-02-15 05:07:46 +00:00
|
|
|
if (mBrowseWithCaret) {
|
|
|
|
nsCOMPtr<nsIContent> caretFocus;
|
|
|
|
PRUint32 caretOffset;
|
|
|
|
GetCaretLocation(getter_AddRefs(caretFocus), &primaryFrame, &caretOffset);
|
|
|
|
}
|
2001-05-22 23:52:17 +00:00
|
|
|
else if (topOfDoc && !mSpecialTopOfDoc) {
|
2001-02-15 05:07:46 +00:00
|
|
|
primaryFrame = nsnull;
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
shell->GetPrimaryFrameFor(mCurrentFocus, &primaryFrame);
|
2001-05-22 23:52:17 +00:00
|
|
|
// Check to see if we are in the special situation
|
|
|
|
// where we are at the top of the document and mSpecialTopOfDoc is set
|
|
|
|
// this means the document is focus and the first piece of content is not
|
|
|
|
if (topOfDoc && mSpecialTopOfDoc) {
|
|
|
|
topOfDoc = PR_FALSE;
|
|
|
|
// so if we are going backwards then find the last piece of content
|
|
|
|
// and and look backwards for the last focusable content
|
|
|
|
if (!forward) {
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
mPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
|
|
|
|
nsCOMPtr<nsIContent> lastContent = getter_AddRefs(GetLastContent(docShell));
|
|
|
|
nsCOMPtr<nsIDOMHTMLIFrameElement> iframe(do_QueryInterface(lastContent));
|
|
|
|
if (iframe) {
|
|
|
|
if (FocusWithinHTMLIFrameDoc(lastContent, forward)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
shell->GetPrimaryFrameFor(lastContent, &primaryFrame);
|
|
|
|
}
|
|
|
|
}
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-05-22 23:52:17 +00:00
|
|
|
PRBool doFocusAvailDocShells = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIContent> next;
|
|
|
|
// rememeber whether mSpecialTopOfDoc was set
|
|
|
|
PRBool wasSpecialDocFocus = mSpecialTopOfDoc;
|
|
|
|
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIContent> rootContent;
|
|
|
|
mDocument->GetRootContent(getter_AddRefs(rootContent));
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2001-05-22 23:52:17 +00:00
|
|
|
// Check here to see if the HTMLFrame wants to do anything special
|
|
|
|
// with the focus. i.e. like focusing a docshell child, or if it
|
|
|
|
// is the last frame in the frameset, it will pass it on to the Chrome
|
|
|
|
if (docType == eFrame && aRoot == nsnull) {
|
|
|
|
if (FocusWithinHTMLFrameDoc(aRoot, shell, forward, doFocusAvailDocShells)) {
|
|
|
|
return;
|
|
|
|
} else if (mSpecialTopOfDoc) {
|
|
|
|
// If we are starting at the top of the document
|
|
|
|
// first check to see if there is a tabbable index to go to
|
|
|
|
//
|
|
|
|
// GetNextTabbableIndexContent may change the value mCurrentTabIndex
|
|
|
|
// so we remember it here and reset it back if it didn't find anything
|
|
|
|
PRInt32 currentTabIndex = mCurrentTabIndex;
|
|
|
|
GetNextTabbableIndexContent(rootContent, forward, PR_TRUE, getter_AddRefs(next));
|
|
|
|
if (next) {
|
|
|
|
topOfDoc = PR_TRUE;
|
|
|
|
} else {
|
|
|
|
mCurrentTabIndex = currentTabIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
//Get the next tab item. This takes tabIndex into account
|
2001-04-18 06:18:10 +00:00
|
|
|
if (!topOfDoc)
|
|
|
|
GetNextTabbableContent(rootContent, primaryFrame, forward, getter_AddRefs(next));
|
|
|
|
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
//Either no tabbable items or the end of the document
|
2000-04-04 23:55:31 +00:00
|
|
|
if (!next) {
|
1999-04-12 21:24:07 +00:00
|
|
|
|
2001-04-18 06:18:10 +00:00
|
|
|
// If we've reached the end of the content in this document, we
|
|
|
|
// focus the document itself before leaving.
|
2001-05-22 23:52:17 +00:00
|
|
|
if (!topOfDoc && !doFocusAvailDocShells) {
|
|
|
|
PRBool focusDoc = PR_TRUE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> docShell;
|
|
|
|
nsCOMPtr<nsIDocShell> parentDS;
|
|
|
|
if (NS_SUCCEEDED(GetDocShellsFromDoc(mDocument, getter_AddRefs(docShell), getter_AddRefs(parentDS)))) {
|
|
|
|
if (docType == eFrame) {
|
|
|
|
if (FocusAfterHTMLFrameDoc(docShell, parentDS, forward)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (docType == eIFrame) {
|
|
|
|
if (FocusAfterHTMLIFrameDoc(docShell, parentDS, forward, focusDoc)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// IFrame may or may not want the current document focused
|
|
|
|
if (focusDoc) {
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> sgo;
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(sgo));
|
|
|
|
nsCOMPtr<nsIDOMWindowInternal> domwin(do_QueryInterface(sgo));
|
|
|
|
if (domwin) {
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
|
|
|
if (NS_SUCCEEDED(domwin->Focus()))
|
|
|
|
return;
|
|
|
|
}
|
2001-04-18 06:18:10 +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
|
|
|
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
//Offer focus upwards to allow shifting focus to UI controls
|
2000-02-11 01:56:01 +00:00
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
mPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(container));
|
|
|
|
if (docShellAsWin) {
|
2001-04-25 02:04:56 +00:00
|
|
|
docShellAsWin->FocusAvailable(docShellAsWin, forward, &focusTaken);
|
2001-05-22 23:52:17 +00:00
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(container);
|
|
|
|
PrintDocTree(node);
|
|
|
|
#endif
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
2000-02-11 01:56:01 +00:00
|
|
|
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
//No one took focus and we're not already at the top of the doc
|
|
|
|
//so calling ShiftFocus will start at the top of the doc again.
|
1999-04-12 21:24:07 +00:00
|
|
|
if (!focusTaken && !topOfDoc) {
|
|
|
|
ShiftFocus(forward);
|
|
|
|
}
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
return;
|
2001-05-22 23:52:17 +00:00
|
|
|
} else {
|
|
|
|
// The "next" piece of content to be focused is an IFrame,
|
|
|
|
// so we need to "walk" into the new HTMLIFrame docShell
|
|
|
|
nsCOMPtr<nsIDOMHTMLIFrameElement> iframe(do_QueryInterface(next));
|
|
|
|
if (iframe) {
|
|
|
|
if (FocusWithinHTMLIFrameDoc(next, forward)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
2001-05-22 23:52:17 +00:00
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
printf("Shift Focus to Content: %p\n", next.get());
|
|
|
|
#endif
|
|
|
|
|
1999-12-21 19:35:13 +00:00
|
|
|
// Now we need to get the content node's frame and reset
|
|
|
|
// the mCurrentTarget target. Otherwise the focus
|
|
|
|
// code will be slightly out of sync (with regards to
|
2000-04-04 23:55:31 +00:00
|
|
|
// focusing widgets within the current target)
|
|
|
|
if (shell)
|
|
|
|
shell->GetPrimaryFrameFor(next, &mCurrentTarget);
|
|
|
|
|
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;
|
2000-04-04 23:55:31 +00:00
|
|
|
NS_IF_ADDREF(mCurrentFocus);
|
2001-05-22 23:52:17 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
mPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
|
|
|
|
if (docShell) {
|
|
|
|
docShell->SetCanvasHasFocus(PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wasSpecialDocFocus) {
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
mPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
|
|
|
|
ForceUpdate(docShell);
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame* aFrame, PRBool forward,
|
|
|
|
nsIContent** aResult)
|
1998-11-18 05:25:26 +00:00
|
|
|
{
|
2000-04-04 23:55:31 +00:00
|
|
|
*aResult = nsnull;
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
PRBool keepFirstFrame = PR_FALSE;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2001-05-22 23:52:17 +00:00
|
|
|
mSpecialTopOfDoc = mCurrentFocus == nsnull;
|
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
|
|
|
|
if (!aFrame) {
|
|
|
|
//No frame means we need to start with the root content again.
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
if (mPresContext) {
|
|
|
|
nsIFrame* result = nsnull;
|
|
|
|
if (NS_SUCCEEDED(mPresContext->GetShell(getter_AddRefs(presShell))) && presShell) {
|
|
|
|
presShell->GetPrimaryFrameFor(aRootContent, &result);
|
|
|
|
}
|
|
|
|
if (result) {
|
|
|
|
while(NS_SUCCEEDED(result->FirstChild(mPresContext, nsnull, &result)) && result) {
|
|
|
|
aFrame = result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!aFrame) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
keepFirstFrame = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Need to do special check in case we're in an imagemap which has multiple content per frame
|
|
|
|
if (mCurrentFocus) {
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
mCurrentFocus->GetTag(*getter_AddRefs(tag));
|
|
|
|
if(nsHTMLAtoms::area==tag.get()) {
|
|
|
|
//Focus is in an imagemap area
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
if (mPresContext) {
|
|
|
|
nsIFrame* result = nsnull;
|
|
|
|
if (NS_SUCCEEDED(mPresContext->GetShell(getter_AddRefs(presShell))) && presShell) {
|
|
|
|
presShell->GetPrimaryFrameFor(mCurrentFocus, &result);
|
|
|
|
}
|
|
|
|
if (result == aFrame) {
|
|
|
|
//The current focus map area is in the current frame, don't skip over it.
|
|
|
|
keepFirstFrame = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-02-19 12:55:42 +00:00
|
|
|
nsresult result;
|
|
|
|
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,&result));
|
|
|
|
if (NS_FAILED(result))
|
|
|
|
return result;
|
1998-11-18 05:25:26 +00:00
|
|
|
|
2001-02-19 12:55:42 +00:00
|
|
|
result = trav->NewFrameTraversal(getter_AddRefs(frameTraversal), EXTENSIVE,
|
|
|
|
mPresContext, aFrame);
|
2000-04-04 23:55:31 +00:00
|
|
|
if (NS_FAILED(result))
|
|
|
|
return NS_OK;
|
1999-03-02 19:19:24 +00:00
|
|
|
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
if (!keepFirstFrame) {
|
|
|
|
if (forward)
|
|
|
|
frameTraversal->Next();
|
|
|
|
else frameTraversal->Prev();
|
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
|
|
|
|
nsISupports* currentItem;
|
|
|
|
frameTraversal->CurrentItem(¤tItem);
|
|
|
|
nsIFrame* currentFrame = (nsIFrame*)currentItem;
|
|
|
|
|
|
|
|
while (currentFrame) {
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
currentFrame->GetContent(getter_AddRefs(child));
|
|
|
|
|
2001-05-31 22:19:43 +00:00
|
|
|
const nsStyleVisibility* vis;
|
|
|
|
currentFrame->GetStyleData(eStyleStruct_Visibility, ((const nsStyleStruct *&)vis));
|
2000-04-04 23:55:31 +00:00
|
|
|
|
|
|
|
const nsStyleUserInterface* ui;
|
2000-08-08 23:48:42 +00:00
|
|
|
currentFrame->GetStyleData(eStyleStruct_UserInterface, ((const nsStyleStruct*&)ui));
|
2001-02-27 04:43:04 +00:00
|
|
|
|
|
|
|
PRBool viewShown = PR_TRUE;
|
|
|
|
|
|
|
|
nsIView* frameView = nsnull;
|
|
|
|
currentFrame->GetView(mPresContext, &frameView);
|
|
|
|
if (!frameView) {
|
|
|
|
nsIFrame* parentWithView = nsnull;
|
|
|
|
currentFrame->GetParentWithView(mPresContext, &parentWithView);
|
|
|
|
if (parentWithView)
|
|
|
|
parentWithView->GetView(mPresContext, &frameView);
|
|
|
|
}
|
|
|
|
while (frameView) {
|
|
|
|
nsViewVisibility visib;
|
|
|
|
frameView->GetVisibility(visib);
|
|
|
|
if (visib == nsViewVisibility_kHide) {
|
|
|
|
viewShown = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
frameView->GetParent(frameView);
|
|
|
|
}
|
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(child));
|
|
|
|
|
|
|
|
// if collapsed or hidden, we don't get tabbed into.
|
2001-02-27 04:43:04 +00:00
|
|
|
if (viewShown &&
|
2001-05-31 22:19:43 +00:00
|
|
|
(vis->mVisible != NS_STYLE_VISIBILITY_COLLAPSE) &&
|
|
|
|
(vis->mVisible != NS_STYLE_VISIBILITY_HIDDEN) &&
|
2000-04-04 23:55:31 +00:00
|
|
|
(ui->mUserFocus != NS_STYLE_USER_FOCUS_IGNORE) &&
|
|
|
|
(ui->mUserFocus != NS_STYLE_USER_FOCUS_NONE) && element) {
|
2000-01-12 06:54:58 +00:00
|
|
|
nsCOMPtr<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
|
|
|
|
2000-01-12 06:54:58 +00:00
|
|
|
child->GetTag(*getter_AddRefs(tag));
|
2000-04-04 23:55:31 +00:00
|
|
|
nsCOMPtr<nsIDOMHTMLElement> htmlElement(do_QueryInterface(child));
|
|
|
|
if (htmlElement) {
|
|
|
|
if (nsHTMLAtoms::input==tag.get()) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> nextInput(do_QueryInterface(child));
|
|
|
|
if (nextInput) {
|
|
|
|
nextInput->GetDisabled(&disabled);
|
|
|
|
nextInput->GetTabIndex(&tabIndex);
|
|
|
|
|
|
|
|
nsAutoString type;
|
|
|
|
nextInput->GetType(type);
|
|
|
|
if (type.EqualsIgnoreCase("hidden")) {
|
|
|
|
hidden = PR_TRUE;
|
|
|
|
}
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
else if (nsHTMLAtoms::select==tag.get()) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> nextSelect(do_QueryInterface(child));
|
|
|
|
if (nextSelect) {
|
|
|
|
nextSelect->GetDisabled(&disabled);
|
|
|
|
nextSelect->GetTabIndex(&tabIndex);
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
else if (nsHTMLAtoms::textarea==tag.get()) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLTextAreaElement> nextTextArea(do_QueryInterface(child));
|
|
|
|
if (nextTextArea) {
|
|
|
|
nextTextArea->GetDisabled(&disabled);
|
|
|
|
nextTextArea->GetTabIndex(&tabIndex);
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
else if(nsHTMLAtoms::a==tag.get()) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLAnchorElement> nextAnchor(do_QueryInterface(child));
|
|
|
|
if (nextAnchor)
|
|
|
|
nextAnchor->GetTabIndex(&tabIndex);
|
2000-05-11 01:43:04 +00:00
|
|
|
nsAutoString href;
|
2001-04-26 19:33:12 +00:00
|
|
|
nextAnchor->GetAttribute(NS_LITERAL_STRING("href"), href);
|
2000-05-11 01:43:04 +00:00
|
|
|
if (!href.Length()) {
|
|
|
|
disabled = PR_TRUE; // Don't tab unless href, bug 17605
|
|
|
|
} else {
|
|
|
|
disabled = PR_FALSE;
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
else if(nsHTMLAtoms::button==tag.get()) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLButtonElement> nextButton(do_QueryInterface(child));
|
|
|
|
if (nextButton) {
|
|
|
|
nextButton->GetTabIndex(&tabIndex);
|
|
|
|
nextButton->GetDisabled(&disabled);
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
else if(nsHTMLAtoms::img==tag.get()) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLImageElement> nextImage(do_QueryInterface(child));
|
|
|
|
nsAutoString usemap;
|
|
|
|
if (nextImage) {
|
2001-04-18 00:14:34 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
if (NS_SUCCEEDED(child->GetDocument(*getter_AddRefs(doc))) && doc) {
|
|
|
|
nextImage->GetAttribute(NS_LITERAL_STRING("usemap"), usemap);
|
|
|
|
nsCOMPtr<nsIDOMHTMLMapElement> imageMap;
|
|
|
|
if (NS_SUCCEEDED(nsImageMapUtils::FindImageMap(doc,usemap,getter_AddRefs(imageMap))) && imageMap) {
|
|
|
|
nsCOMPtr<nsIContent> map(do_QueryInterface(imageMap));
|
|
|
|
if (map) {
|
|
|
|
nsCOMPtr<nsIContent> childArea;
|
|
|
|
PRInt32 count, index;
|
|
|
|
map->ChildCount(count);
|
|
|
|
//First see if mCurrentFocus is in this map
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
map->ChildAt(index, *getter_AddRefs(childArea));
|
|
|
|
if (childArea.get() == mCurrentFocus) {
|
|
|
|
nsAutoString tabIndexStr;
|
|
|
|
childArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndexStr);
|
2001-05-04 05:34:58 +00:00
|
|
|
PRInt32 val = 0;
|
|
|
|
if (!tabIndexStr.IsEmpty()) {
|
|
|
|
PRInt32 ec, tabIndexVal = tabIndexStr.ToInteger(&ec);
|
|
|
|
if (NS_SUCCEEDED(ec)) {
|
|
|
|
val = tabIndexVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mCurrentTabIndex == val) {
|
2001-04-18 00:14:34 +00:00
|
|
|
//mCurrentFocus is in this map so we must start iterating past it.
|
|
|
|
//We skip the case where mCurrentFocus has the same tab index
|
|
|
|
//as mCurrentTabIndex since the next tab ordered element might
|
|
|
|
//be before it (or after for backwards) in the child list.
|
|
|
|
break;
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-04-18 00:14:34 +00:00
|
|
|
PRInt32 increment = forward ? 1 : - 1;
|
|
|
|
PRInt32 start = index < count ? index + increment : (forward ? 0 : count - 1);
|
|
|
|
for (index = start; index < count && index >= 0; index += increment) {
|
|
|
|
//Iterate over the children.
|
|
|
|
map->ChildAt(index, *getter_AddRefs(childArea));
|
|
|
|
|
|
|
|
//Got the map area, check its tabindex.
|
|
|
|
nsAutoString tabIndexStr;
|
|
|
|
childArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndexStr);
|
2001-05-04 05:34:58 +00:00
|
|
|
PRInt32 val = 0;
|
|
|
|
if (!tabIndexStr.IsEmpty()) {
|
|
|
|
PRInt32 ec, tabIndexVal = tabIndexStr.ToInteger(&ec);
|
|
|
|
if (NS_SUCCEEDED(ec)) {
|
|
|
|
val = tabIndexVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mCurrentTabIndex == val) {
|
2001-04-18 00:14:34 +00:00
|
|
|
//tabindex == the current one, use it.
|
|
|
|
*aResult = childArea;
|
|
|
|
NS_IF_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
else if(nsHTMLAtoms::object==tag.get()) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLObjectElement> nextObject(do_QueryInterface(child));
|
|
|
|
if (nextObject)
|
|
|
|
nextObject->GetTabIndex(&tabIndex);
|
|
|
|
disabled = PR_FALSE;
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
2001-05-22 23:52:17 +00:00
|
|
|
else if (nsHTMLAtoms::iframe==tag.get()) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLIFrameElement> iframe(do_QueryInterface(child));
|
|
|
|
if (iframe) {
|
|
|
|
disabled = PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
2000-03-23 09:56:58 +00:00
|
|
|
else {
|
2000-04-04 23:55:31 +00:00
|
|
|
nsAutoString value;
|
|
|
|
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::disabled, value);
|
|
|
|
nsAutoString tabStr;
|
|
|
|
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::tabindex, tabStr);
|
2000-04-15 20:15:37 +00:00
|
|
|
if (!tabStr.IsEmpty()) {
|
2000-04-04 23:55:31 +00:00
|
|
|
PRInt32 errorCode;
|
|
|
|
tabIndex = tabStr.ToInteger(&errorCode);
|
2000-03-23 09:56:58 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
if (!value.EqualsWithConversion("true"))
|
|
|
|
disabled = PR_FALSE;
|
2000-01-13 11:43:54 +00:00
|
|
|
}
|
2000-03-23 09:56:58 +00:00
|
|
|
|
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;
|
|
|
|
|
2001-01-19 01:28:27 +00:00
|
|
|
if (!disabled && !hidden && mCurrentTabIndex == tabIndex && child.get() != mCurrentFocus) {
|
2000-04-04 23:55:31 +00:00
|
|
|
*aResult = child;
|
|
|
|
NS_IF_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
if (forward)
|
|
|
|
frameTraversal->Next();
|
|
|
|
else frameTraversal->Prev();
|
|
|
|
|
|
|
|
frameTraversal->CurrentItem(¤tItem);
|
|
|
|
currentFrame = (nsIFrame*)currentItem;
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
// Reached end or beginning of document
|
|
|
|
//If already at lowest priority tab (0), end
|
|
|
|
if (((forward) && (0 == mCurrentTabIndex)) ||
|
|
|
|
((!forward) && (1 == mCurrentTabIndex))) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
//else continue looking for next highest priority tab
|
|
|
|
mCurrentTabIndex = GetNextTabIndex(aRootContent, forward);
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
return GetNextTabbableContent(aRootContent, nsnull, forward, aResult);
|
1998-11-18 05:25:26 +00:00
|
|
|
}
|
|
|
|
|
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;
|
2000-04-04 23:55:31 +00:00
|
|
|
nsCOMPtr<nsIContent> child;
|
1999-07-19 21:23:57 +00:00
|
|
|
|
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++) {
|
2000-04-04 23:55:31 +00:00
|
|
|
aParent->ChildAt(index, *getter_AddRefs(child));
|
1999-07-19 21:23:57 +00:00
|
|
|
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;
|
|
|
|
}
|
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++) {
|
2000-04-04 23:55:31 +00:00
|
|
|
aParent->ChildAt(index, *getter_AddRefs(child));
|
1999-07-19 21:23:57 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return tabIndex;
|
|
|
|
}
|
|
|
|
|
2001-05-22 23:52:17 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::GetNextTabbableIndexContent(nsIContent* aRootContent,
|
|
|
|
PRBool forward,
|
|
|
|
PRBool aStartOver,
|
|
|
|
nsIContent** aResult)
|
|
|
|
{
|
|
|
|
if (forward) {
|
|
|
|
if (aStartOver) {
|
|
|
|
mCurrentTabIndex = 0;
|
|
|
|
}
|
|
|
|
mCurrentTabIndex = GetNextTabIndex(aRootContent, forward);
|
|
|
|
if (mCurrentTabIndex > 0) {
|
|
|
|
return GetNextTabbableContent(aRootContent, nsnull, forward, aResult);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
nsCOMPtr<nsIContent> lastContent = getter_AddRefs(GetLastContent(aRootContent));
|
|
|
|
if (lastContent) {
|
|
|
|
MoveFocus(PR_FALSE, lastContent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-06-24 03:58:13 +00:00
|
|
|
if (!mCurrentTarget) {
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
mPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
if (presShell) {
|
|
|
|
presShell->GetEventTargetFrame(&mCurrentTarget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
*aFrame = mCurrentTarget;
|
1999-07-27 20:55:03 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-05-22 23:52:17 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::HasPositiveTabIndex(nsIContent* aContent,
|
|
|
|
PRBool* aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aContent);
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
*aResult = PR_FALSE;
|
|
|
|
|
|
|
|
nsAutoString tabIndexStr;
|
|
|
|
aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndexStr);
|
|
|
|
if (!tabIndexStr.IsEmpty()) {
|
|
|
|
PRInt32 ec, tabIndexVal = tabIndexStr.ToInteger(&ec);
|
|
|
|
if (NS_SUCCEEDED(ec)) {
|
|
|
|
if (tabIndexVal > 0) {
|
|
|
|
*aResult = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 count;
|
|
|
|
aContent->ChildCount(count);
|
|
|
|
for (PRInt32 i=0;i<count;i++) {
|
|
|
|
nsIContent* child;
|
|
|
|
aContent->ChildAt(i, child);
|
|
|
|
if (NS_SUCCEEDED(HasPositiveTabIndex(child, aResult))) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
1999-07-27 20:55:03 +00:00
|
|
|
NS_IMETHODIMP
|
1999-12-08 04:54:29 +00:00
|
|
|
nsEventStateManager::GetEventTargetContent(nsEvent* aEvent, nsIContent** aContent)
|
1999-07-27 20:55:03 +00:00
|
|
|
{
|
1999-12-08 09:01:06 +00:00
|
|
|
if (aEvent &&
|
|
|
|
(aEvent->message == NS_FOCUS_CONTENT ||
|
|
|
|
aEvent->message == NS_BLUR_CONTENT)) {
|
1999-12-08 04:54:29 +00:00
|
|
|
*aContent = mCurrentFocus;
|
|
|
|
NS_IF_ADDREF(*aContent);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-07-27 20:55:03 +00:00
|
|
|
if (mCurrentTargetContent) {
|
|
|
|
*aContent = mCurrentTargetContent;
|
|
|
|
NS_IF_ADDREF(*aContent);
|
2000-08-14 22:29:03 +00:00
|
|
|
return NS_OK;
|
1999-07-27 20:55:03 +00:00
|
|
|
}
|
2000-06-24 03:58:13 +00:00
|
|
|
|
|
|
|
if (!mCurrentTarget) {
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
mPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
if (presShell) {
|
|
|
|
presShell->GetEventTargetFrame(&mCurrentTarget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-07-27 20:55:03 +00:00
|
|
|
if (mCurrentTarget) {
|
2000-02-11 01:24:59 +00:00
|
|
|
mCurrentTarget->GetContentForEvent(mPresContext, aEvent, aContent);
|
1999-07-27 20:55:03 +00:00
|
|
|
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
|
|
|
}
|
2000-09-15 06:17:54 +00:00
|
|
|
if (hHover) {
|
|
|
|
//If using hierchical hover check the ancestor chain of mHoverContent
|
|
|
|
//to see if we are on it.
|
|
|
|
nsCOMPtr<nsIContent> parent = mHoverContent;
|
|
|
|
nsIContent* child;
|
|
|
|
while (parent) {
|
2000-09-15 06:58:32 +00:00
|
|
|
if (aContent == parent.get()) {
|
2000-09-15 06:17:54 +00:00
|
|
|
aState |= NS_EVENT_STATE_HOVER;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
child = parent;
|
|
|
|
child->GetParent(*getter_AddRefs(parent));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (aContent == mHoverContent) {
|
|
|
|
aState |= NS_EVENT_STATE_HOVER;
|
|
|
|
}
|
1999-01-28 23:14:36 +00:00
|
|
|
}
|
2000-10-16 21:52:22 +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};
|
|
|
|
|
2000-08-08 23:48:42 +00:00
|
|
|
// check to see that this state is allowed by style. Check dragover too?
|
|
|
|
if (mCurrentTarget && (aState == NS_EVENT_STATE_ACTIVE || aState == NS_EVENT_STATE_HOVER))
|
|
|
|
{
|
|
|
|
const nsStyleUserInterface* ui;
|
|
|
|
mCurrentTarget->GetStyleData(eStyleStruct_UserInterface, ((const nsStyleStruct*&)ui));
|
|
|
|
if (ui->mUserInput == NS_STYLE_USER_INPUT_NONE)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-05-04 14:44:51 +00:00
|
|
|
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
|
|
|
|
2000-09-15 06:17:54 +00:00
|
|
|
nsCOMPtr<nsIContent> newHover = nsnull;
|
|
|
|
nsCOMPtr<nsIContent> oldHover = nsnull;
|
|
|
|
nsCOMPtr<nsIContent> commonHoverParent = nsnull;
|
1999-04-20 00:03:30 +00:00
|
|
|
if ((aState & NS_EVENT_STATE_HOVER) && (aContent != mHoverContent)) {
|
2000-09-15 06:17:54 +00:00
|
|
|
if (hHover) {
|
2000-09-27 14:34:50 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
if (aContent && NS_SUCCEEDED(aContent->GetDocument(*getter_AddRefs(doc))) && doc) {
|
|
|
|
newHover = aContent;
|
|
|
|
}
|
|
|
|
if (mHoverContent && NS_SUCCEEDED(mHoverContent->GetDocument(*getter_AddRefs(doc))) && doc) {
|
|
|
|
oldHover = mHoverContent;
|
|
|
|
}
|
2000-09-15 06:17:54 +00:00
|
|
|
|
|
|
|
//Find closest common parent
|
|
|
|
nsCOMPtr<nsIContent> parent1 = mHoverContent;
|
|
|
|
nsCOMPtr<nsIContent> parent2;
|
|
|
|
if (mHoverContent && aContent) {
|
|
|
|
while (parent1) {
|
|
|
|
parent2 = aContent;
|
|
|
|
while (parent2) {
|
|
|
|
if (parent1 == parent2) {
|
|
|
|
commonHoverParent = parent1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsIContent* child2 = parent2;
|
|
|
|
child2->GetParent(*getter_AddRefs(parent2));
|
|
|
|
}
|
|
|
|
if (commonHoverParent) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsIContent* child1 = parent1;
|
|
|
|
child1->GetParent(*getter_AddRefs(parent1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//If new hover content is null we get the top parent of mHoverContent
|
|
|
|
else if (mHoverContent) {
|
|
|
|
nsCOMPtr<nsIContent> parent = mHoverContent;
|
|
|
|
nsIContent* child = nsnull;
|
|
|
|
while (parent) {
|
|
|
|
child = parent;
|
|
|
|
child->GetParent(*getter_AddRefs(parent));
|
|
|
|
}
|
|
|
|
commonHoverParent = child;
|
|
|
|
}
|
|
|
|
//Else if old hover content is null we get the top parent of aContent
|
|
|
|
else {
|
|
|
|
nsCOMPtr<nsIContent> parent = aContent;
|
|
|
|
nsIContent* child = nsnull;
|
|
|
|
while (parent) {
|
|
|
|
child = parent;
|
|
|
|
child->GetParent(*getter_AddRefs(parent));
|
|
|
|
}
|
|
|
|
commonHoverParent = child;
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(mHoverContent);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
//transferring ref to notifyContent from mHoverContent
|
|
|
|
notifyContent[1] = mHoverContent; // notify hover first, since more common case
|
|
|
|
}
|
1999-04-20 00:03:30 +00:00
|
|
|
mHoverContent = aContent;
|
|
|
|
NS_IF_ADDREF(mHoverContent);
|
1998-08-07 04:45:03 +00:00
|
|
|
}
|
|
|
|
|
1999-12-08 04:54:29 +00:00
|
|
|
if ((aState & NS_EVENT_STATE_FOCUS)) {
|
2000-06-14 02:59:54 +00:00
|
|
|
if (aContent && (aContent == mCurrentFocus) && gLastFocusedDocument == mDocument) {
|
2000-03-02 23:15:01 +00:00
|
|
|
// gLastFocusedDocument appears to always be correct, that is why
|
|
|
|
// I'm not setting it here. This is to catch an edge case.
|
|
|
|
NS_IF_RELEASE(gLastFocusedContent);
|
|
|
|
gLastFocusedContent = mCurrentFocus;
|
|
|
|
NS_IF_ADDREF(gLastFocusedContent);
|
2001-02-07 07:05:56 +00:00
|
|
|
//If this notification was for focus alone then get rid of aContent
|
|
|
|
//ref to avoid unnecessary notification.
|
|
|
|
if (!(aState & ~NS_EVENT_STATE_FOCUS)) {
|
|
|
|
aContent = nsnull;
|
|
|
|
}
|
1999-12-08 04:54:29 +00:00
|
|
|
} else {
|
2000-04-12 00:24:07 +00:00
|
|
|
notifyContent[3] = gLastFocusedContent;
|
|
|
|
NS_IF_ADDREF(gLastFocusedContent);
|
2000-04-04 23:55:31 +00:00
|
|
|
SendFocusBlur(mPresContext, aContent);
|
1999-12-08 04:54:29 +00:00
|
|
|
}
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-15 06:17:54 +00:00
|
|
|
if (notifyContent[0] || newHover || oldHover) { // have at least one to notify about
|
2001-05-14 01:49:07 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc1, doc2; // this presumes content can't get/lose state if not connected to doc
|
2000-09-15 06:17:54 +00:00
|
|
|
if (notifyContent[0]) {
|
2001-05-14 01:49:07 +00:00
|
|
|
notifyContent[0]->GetDocument(*getter_AddRefs(doc1));
|
|
|
|
if (notifyContent[1]) {
|
|
|
|
//For :focus this might be a different doc so check
|
|
|
|
notifyContent[1]->GetDocument(*getter_AddRefs(doc2));
|
|
|
|
if (doc1 == doc2) {
|
|
|
|
doc2 = nsnull;
|
|
|
|
}
|
|
|
|
}
|
2000-09-15 06:17:54 +00:00
|
|
|
}
|
|
|
|
else if (newHover) {
|
2001-05-14 01:49:07 +00:00
|
|
|
newHover->GetDocument(*getter_AddRefs(doc1));
|
2000-09-15 06:17:54 +00:00
|
|
|
}
|
|
|
|
else {
|
2001-05-14 01:49:07 +00:00
|
|
|
oldHover->GetDocument(*getter_AddRefs(doc2));
|
2000-09-15 06:17:54 +00:00
|
|
|
}
|
2001-05-14 01:49:07 +00:00
|
|
|
if (doc1) {
|
|
|
|
doc1->BeginUpdate();
|
2000-09-15 06:17:54 +00:00
|
|
|
|
|
|
|
//Notify all content from newHover to the commonHoverParent
|
|
|
|
if (newHover) {
|
|
|
|
nsCOMPtr<nsIContent> parent;
|
|
|
|
newHover->GetParent(*getter_AddRefs(parent));
|
2001-05-14 01:49:07 +00:00
|
|
|
doc1->ContentStatesChanged(newHover, parent);
|
2000-09-15 06:17:54 +00:00
|
|
|
while (parent && parent != commonHoverParent) {
|
|
|
|
parent->GetParent(*getter_AddRefs(newHover));
|
|
|
|
if (newHover && newHover != commonHoverParent) {
|
|
|
|
newHover->GetParent(*getter_AddRefs(parent));
|
2000-09-15 07:46:15 +00:00
|
|
|
if (parent == commonHoverParent) {
|
2001-05-14 01:49:07 +00:00
|
|
|
doc1->ContentStatesChanged(newHover, nsnull);
|
2000-09-15 07:46:15 +00:00
|
|
|
}
|
|
|
|
else {
|
2001-05-14 01:49:07 +00:00
|
|
|
doc1->ContentStatesChanged(newHover, parent);
|
2000-09-15 07:46:15 +00:00
|
|
|
}
|
2000-09-15 06:17:54 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//Notify all content from oldHover to the commonHoverParent
|
|
|
|
if (oldHover) {
|
|
|
|
nsCOMPtr<nsIContent> parent;
|
|
|
|
oldHover->GetParent(*getter_AddRefs(parent));
|
2001-05-14 01:49:07 +00:00
|
|
|
doc1->ContentStatesChanged(oldHover, parent);
|
2000-09-15 06:17:54 +00:00
|
|
|
while (parent && parent != commonHoverParent) {
|
|
|
|
parent->GetParent(*getter_AddRefs(oldHover));
|
|
|
|
if (oldHover && oldHover != commonHoverParent) {
|
|
|
|
oldHover->GetParent(*getter_AddRefs(parent));
|
2000-09-15 07:46:15 +00:00
|
|
|
if (parent == commonHoverParent) {
|
2001-05-14 01:49:07 +00:00
|
|
|
doc1->ContentStatesChanged(oldHover, nsnull);
|
2000-09-15 07:46:15 +00:00
|
|
|
}
|
|
|
|
else {
|
2001-05-14 01:49:07 +00:00
|
|
|
doc1->ContentStatesChanged(oldHover, parent);
|
2000-09-15 07:46:15 +00:00
|
|
|
}
|
2000-09-15 06:17:54 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-05-14 01:49:07 +00:00
|
|
|
doc1->ContentStatesChanged(notifyContent[0], notifyContent[1]);
|
1999-04-20 00:03:30 +00:00
|
|
|
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))
|
2001-05-14 01:49:07 +00:00
|
|
|
doc1->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)
|
2001-05-14 01:49:07 +00:00
|
|
|
doc1->ContentStatesChanged(notifyContent[4], nsnull);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
doc1->EndUpdate();
|
|
|
|
|
|
|
|
if (doc2) {
|
|
|
|
doc2->BeginUpdate();
|
|
|
|
doc2->ContentStatesChanged(notifyContent[1], notifyContent[2]);
|
|
|
|
if (notifyContent[3]) {
|
|
|
|
doc1->ContentStatesChanged(notifyContent[3], notifyContent[4]);
|
1999-05-04 14:44:51 +00:00
|
|
|
}
|
2001-05-14 01:49:07 +00:00
|
|
|
doc2->EndUpdate();
|
1999-04-20 00:03:30 +00:00
|
|
|
}
|
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
|
|
|
{
|
1999-12-21 19:35:13 +00:00
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
2000-04-04 23:55:31 +00:00
|
|
|
|
1999-12-18 04:02:28 +00:00
|
|
|
if (nsnull != gLastFocusedPresContext) {
|
|
|
|
|
2000-02-11 05:20:44 +00:00
|
|
|
if (gLastFocusedContent && gLastFocusedContent != mFirstBlurEvent) {
|
|
|
|
|
|
|
|
//Store the first blur event we fire and don't refire blur
|
|
|
|
//to that element while the first blur is still ongoing.
|
|
|
|
PRBool clearFirstBlurEvent = PR_FALSE;
|
|
|
|
if (!mFirstBlurEvent) {
|
|
|
|
mFirstBlurEvent = gLastFocusedContent;
|
|
|
|
NS_ADDREF(mFirstBlurEvent);
|
|
|
|
clearFirstBlurEvent = PR_TRUE;
|
|
|
|
}
|
1999-12-18 04:02:28 +00:00
|
|
|
|
|
|
|
// Retrieve this content node's pres context. it can be out of sync in
|
|
|
|
// the Ender widget case.
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
gLastFocusedContent->GetDocument(*getter_AddRefs(doc));
|
1999-12-21 19:35:13 +00:00
|
|
|
if (doc) {
|
2000-10-18 17:41:14 +00:00
|
|
|
// The order of the nsIViewManager and nsIPresShell COM pointers is
|
|
|
|
// important below. We want the pres shell to get released before the
|
|
|
|
// associated view manager on exit from this function.
|
|
|
|
// See bug 53763.
|
|
|
|
nsCOMPtr<nsIViewManager> kungFuDeathGrip;
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
doc->GetShellAt(0, getter_AddRefs(shell));
|
2000-04-05 02:10:25 +00:00
|
|
|
if (shell) {
|
2000-10-18 17:41:14 +00:00
|
|
|
shell->GetViewManager(getter_AddRefs(kungFuDeathGrip));
|
|
|
|
|
2000-04-05 02:10:25 +00:00
|
|
|
nsCOMPtr<nsIPresContext> oldPresContext;
|
|
|
|
shell->GetPresContext(getter_AddRefs(oldPresContext));
|
1999-12-21 01:12:40 +00:00
|
|
|
|
2000-04-05 02:10:25 +00:00
|
|
|
//fire blur
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
2000-06-28 20:35:32 +00:00
|
|
|
|
2000-06-29 20:53:08 +00:00
|
|
|
EnsureDocument(presShell);
|
2000-06-28 20:35:32 +00:00
|
|
|
|
|
|
|
// Make sure we're not switching command dispatchers, if so, surpress the blurred one
|
|
|
|
if(gLastFocusedDocument && mDocument) {
|
2000-11-04 08:21:20 +00:00
|
|
|
nsCOMPtr<nsIFocusController> newFocusController;
|
|
|
|
nsCOMPtr<nsIFocusController> oldFocusController;
|
2000-06-28 20:35:32 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindow> oldPIDOMWindow;
|
|
|
|
nsCOMPtr<nsPIDOMWindow> newPIDOMWindow;
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> oldGlobal;
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> newGlobal;
|
|
|
|
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(oldGlobal));
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(newGlobal));
|
2000-06-23 05:37:08 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(newGlobal);
|
2000-06-28 20:35:32 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(oldGlobal);
|
2000-07-07 22:17:00 +00:00
|
|
|
if(newWindow)
|
2000-11-04 08:21:20 +00:00
|
|
|
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
|
2000-07-07 22:17:00 +00:00
|
|
|
if(oldWindow)
|
2000-11-04 08:21:20 +00:00
|
|
|
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
|
|
|
|
if(oldFocusController && oldFocusController != newFocusController)
|
2001-04-18 01:41:20 +00:00
|
|
|
oldFocusController->SetSuppressFocus(PR_TRUE, "SendFocusBlur Window Switch");
|
2000-06-28 20:35:32 +00:00
|
|
|
}
|
|
|
|
|
2000-04-05 02:10:25 +00:00
|
|
|
nsCOMPtr<nsIEventStateManager> esm;
|
|
|
|
oldPresContext->GetEventStateManager(getter_AddRefs(esm));
|
|
|
|
esm->SetFocusedContent(gLastFocusedContent);
|
|
|
|
nsCOMPtr<nsIContent> temp = gLastFocusedContent;
|
|
|
|
NS_RELEASE(gLastFocusedContent);
|
|
|
|
gLastFocusedContent = nsnull;
|
|
|
|
temp->HandleDOMEvent(oldPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
esm->SetFocusedContent(nsnull);
|
|
|
|
}
|
1999-12-21 01:12:40 +00:00
|
|
|
}
|
2000-02-11 05:20:44 +00:00
|
|
|
|
|
|
|
if (clearFirstBlurEvent) {
|
|
|
|
NS_RELEASE(mFirstBlurEvent);
|
|
|
|
}
|
1999-12-18 04:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Go ahead and fire a blur on the window.
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
2000-02-11 01:24:59 +00:00
|
|
|
|
2000-02-12 08:33:12 +00:00
|
|
|
if(gLastFocusedDocument)
|
|
|
|
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
2000-06-28 20:35:32 +00:00
|
|
|
|
|
|
|
EnsureDocument(presShell);
|
1999-12-18 04:02:28 +00:00
|
|
|
|
2000-02-12 08:33:12 +00:00
|
|
|
if (gLastFocusedDocument && (gLastFocusedDocument != mDocument) && globalObject) {
|
1999-12-18 04:02:28 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
nsEvent event;
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
event.message = NS_BLUR_CONTENT;
|
|
|
|
|
2000-06-23 05:37:08 +00:00
|
|
|
// Make sure we're not switching command dispatchers, if so, surpress the blurred one
|
|
|
|
if(mDocument) {
|
2000-11-04 08:21:20 +00:00
|
|
|
nsCOMPtr<nsIFocusController> newFocusController;
|
|
|
|
nsCOMPtr<nsIFocusController> oldFocusController;
|
2000-06-23 05:37:08 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindow> oldPIDOMWindow;
|
|
|
|
nsCOMPtr<nsPIDOMWindow> newPIDOMWindow;
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> oldGlobal;
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> newGlobal;
|
|
|
|
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(oldGlobal));
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(newGlobal));
|
|
|
|
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(newGlobal);
|
|
|
|
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(oldGlobal);
|
|
|
|
|
2001-05-01 22:54:11 +00:00
|
|
|
if (newWindow)
|
|
|
|
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
|
2000-11-04 08:21:20 +00:00
|
|
|
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
|
|
|
|
if(oldFocusController && oldFocusController != newFocusController)
|
2001-04-18 01:41:20 +00:00
|
|
|
oldFocusController->SetSuppressFocus(PR_TRUE, "SendFocusBlur Window Switch #2");
|
2000-06-23 05:37:08 +00:00
|
|
|
}
|
|
|
|
|
1999-12-18 04:02:28 +00:00
|
|
|
nsCOMPtr<nsIEventStateManager> esm;
|
|
|
|
gLastFocusedPresContext->GetEventStateManager(getter_AddRefs(esm));
|
|
|
|
esm->SetFocusedContent(nsnull);
|
2000-02-12 08:33:12 +00:00
|
|
|
nsCOMPtr<nsIDocument> temp = gLastFocusedDocument;
|
|
|
|
NS_RELEASE(gLastFocusedDocument);
|
|
|
|
gLastFocusedDocument = nsnull;
|
|
|
|
temp->HandleDOMEvent(gLastFocusedPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1999-12-18 04:02:28 +00:00
|
|
|
globalObject->HandleDOMEvent(gLastFocusedPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
1999-12-08 04:54:29 +00:00
|
|
|
|
|
|
|
NS_IF_RELEASE(gLastFocusedContent);
|
|
|
|
NS_IF_RELEASE(mCurrentFocus);
|
|
|
|
gLastFocusedContent = aContent;
|
|
|
|
mCurrentFocus = aContent;
|
|
|
|
NS_IF_ADDREF(aContent);
|
|
|
|
NS_IF_ADDREF(aContent);
|
|
|
|
|
2000-02-11 05:20:44 +00:00
|
|
|
if (nsnull != aContent && aContent != mFirstFocusEvent) {
|
|
|
|
|
|
|
|
//Store the first focus event we fire and don't refire focus
|
|
|
|
//to that element while the first focus is still ongoing.
|
|
|
|
PRBool clearFirstFocusEvent = PR_FALSE;
|
|
|
|
if (!mFirstFocusEvent) {
|
|
|
|
mFirstFocusEvent = aContent;
|
|
|
|
NS_ADDREF(mFirstFocusEvent);
|
|
|
|
clearFirstFocusEvent = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
1999-04-12 21:24:07 +00:00
|
|
|
//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-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-12-08 04:54:29 +00:00
|
|
|
|
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;
|
|
|
|
}
|
2000-02-11 05:20:44 +00:00
|
|
|
|
|
|
|
if (clearFirstFocusEvent) {
|
|
|
|
NS_RELEASE(mFirstFocusEvent);
|
|
|
|
}
|
1999-12-08 04:54:29 +00:00
|
|
|
}
|
1999-09-20 22:18:57 +00:00
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
nsIFrame * currentFocusFrame = nsnull;
|
|
|
|
if (mCurrentFocus)
|
|
|
|
presShell->GetPrimaryFrameFor(mCurrentFocus, ¤tFocusFrame);
|
|
|
|
if (!currentFocusFrame)
|
|
|
|
currentFocusFrame = mCurrentTarget;
|
1999-12-08 04:54:29 +00:00
|
|
|
|
|
|
|
// Find the window that this frame is in and
|
|
|
|
// make sure it has focus
|
2001-04-12 23:39:19 +00:00
|
|
|
if (currentFocusFrame) {
|
1999-12-08 04:54:29 +00:00
|
|
|
nsIFrame * parentFrame;
|
|
|
|
currentFocusFrame->GetParentWithView(aPresContext, &parentFrame);
|
|
|
|
if (nsnull != parentFrame) {
|
|
|
|
nsIView * pView;
|
|
|
|
parentFrame->GetView(aPresContext, &pView);
|
|
|
|
if (nsnull != pView) {
|
1999-09-20 22:18:57 +00:00
|
|
|
nsIWidget *window = nsnull;
|
|
|
|
|
1999-12-08 04:54:29 +00:00
|
|
|
nsIView *ancestor = pView;
|
|
|
|
while (nsnull != ancestor) {
|
|
|
|
ancestor->GetWidget(window); // addrefs
|
|
|
|
if (nsnull != window) {
|
2000-01-19 03:03:09 +00:00
|
|
|
window->SetFocus();
|
|
|
|
NS_RELEASE(window); // releases. Duh.
|
1999-12-08 04:54:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
ancestor->GetParent(ancestor);
|
1999-09-20 22:18:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-11-13 05:16:33 +00:00
|
|
|
}
|
2001-02-15 05:07:46 +00:00
|
|
|
|
|
|
|
// For accessibility.browsewithcaret option, we must make the caret visible in text nodes
|
|
|
|
if (presShell && mBrowseWithCaret)
|
|
|
|
EnsureCaretVisible(presShell, aContent);
|
|
|
|
|
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-12-08 04:54:29 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::SetFocusedContent(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
NS_IF_RELEASE(mCurrentFocus);
|
|
|
|
mCurrentFocus = aContent;
|
|
|
|
NS_IF_ADDREF(mCurrentFocus);
|
2001-05-22 23:52:17 +00:00
|
|
|
mSpecialTopOfDoc = PR_FALSE;
|
1999-12-08 04:54:29 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-02-09 15:14:55 +00:00
|
|
|
//-------------------------------------------
|
|
|
|
// Access Key Registration
|
|
|
|
//-------------------------------------------
|
|
|
|
NS_IMETHODIMP
|
2000-05-16 10:22:20 +00:00
|
|
|
nsEventStateManager::RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey)
|
2000-02-09 15:14:55 +00:00
|
|
|
{
|
2000-05-16 10:22:20 +00:00
|
|
|
if (!mAccessKeys) {
|
|
|
|
mAccessKeys = new nsSupportsHashtable();
|
|
|
|
if (!mAccessKeys) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
if (!aContent) {
|
|
|
|
aFrame->GetContent(getter_AddRefs(content));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
content = aContent;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (content) {
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
nsAutoString accKey((char)aKey);
|
|
|
|
accKey.ToLowerCase();
|
|
|
|
|
|
|
|
nsVoidKey key((void*)accKey.First());
|
2000-05-16 10:22:20 +00:00
|
|
|
|
2000-06-06 22:06:56 +00:00
|
|
|
mAccessKeys->Put(&key, content);
|
2000-05-16 10:22:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
2000-02-09 15:14:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-05-16 10:22:20 +00:00
|
|
|
nsEventStateManager::UnregisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey)
|
2000-02-09 15:14:55 +00:00
|
|
|
{
|
2000-05-16 10:22:20 +00:00
|
|
|
if (!mAccessKeys) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
if (!aContent) {
|
|
|
|
aFrame->GetContent(getter_AddRefs(content));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
content = aContent;
|
|
|
|
}
|
|
|
|
if (content) {
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
nsAutoString accKey((char)aKey);
|
|
|
|
accKey.ToLowerCase();
|
|
|
|
|
|
|
|
nsVoidKey key((void*)accKey.First());
|
2000-05-16 10:22:20 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> oldContent = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key)));
|
|
|
|
if (oldContent != content) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
mAccessKeys->Remove(&key);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
2000-02-09 15:14:55 +00:00
|
|
|
}
|
|
|
|
|
2000-01-11 22:30:22 +00:00
|
|
|
void nsEventStateManager::ForceViewUpdate(nsIView* aView)
|
|
|
|
{
|
|
|
|
// 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();
|
2000-01-26 23:04:40 +00:00
|
|
|
vm->ForceUpdate();
|
2000-01-11 22:30:22 +00:00
|
|
|
NS_RELEASE(vm);
|
|
|
|
}
|
|
|
|
}
|
1999-11-21 01:46:41 +00:00
|
|
|
|
2000-05-16 11:35:12 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::DispatchNewEvent(nsISupports* aTarget, nsIDOMEvent* aEvent)
|
|
|
|
{
|
2000-05-17 05:27:22 +00:00
|
|
|
nsresult ret = NS_OK;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrivateDOMEvent> privEvt(do_QueryInterface(aEvent));
|
|
|
|
if (aEvent) {
|
|
|
|
nsEvent* innerEvent;
|
|
|
|
privEvt->GetInternalNSEvent(&innerEvent);
|
|
|
|
if (innerEvent) {
|
2000-11-08 00:33:37 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
2000-05-17 05:27:22 +00:00
|
|
|
nsCOMPtr<nsIScriptGlobalObject> target(do_QueryInterface(aTarget));
|
|
|
|
if (target) {
|
|
|
|
ret = target->HandleDOMEvent(mPresContext, innerEvent, &aEvent, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsCOMPtr<nsIDocument> target(do_QueryInterface(aTarget));
|
|
|
|
if (target) {
|
|
|
|
ret = target->HandleDOMEvent(mPresContext, innerEvent, &aEvent, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsCOMPtr<nsIContent> target(do_QueryInterface(aTarget));
|
|
|
|
if (target) {
|
|
|
|
ret = target->HandleDOMEvent(mPresContext, innerEvent, &aEvent, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
2000-11-04 08:21:20 +00:00
|
|
|
else {
|
|
|
|
nsCOMPtr<nsIChromeEventHandler> target(do_QueryInterface(aTarget));
|
|
|
|
if (target) {
|
|
|
|
ret = target->HandleChromeEvent(mPresContext, innerEvent, &aEvent, NS_EVENT_FLAG_INIT, &status);
|
|
|
|
}
|
|
|
|
}
|
2000-05-17 05:27:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
2000-05-16 11:35:12 +00:00
|
|
|
}
|
|
|
|
|
2000-06-28 20:35:32 +00:00
|
|
|
void nsEventStateManager::EnsureDocument(nsIPresContext* aPresContext) {
|
|
|
|
if (!mDocument) {
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
EnsureDocument(presShell);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsEventStateManager::EnsureDocument(nsIPresShell* aPresShell) {
|
|
|
|
if (!mDocument && aPresShell)
|
|
|
|
aPresShell->GetDocument(&mDocument);
|
|
|
|
}
|
|
|
|
|
2001-01-20 04:59:39 +00:00
|
|
|
void nsEventStateManager::FlushPendingEvents(nsIPresContext* aPresContext) {
|
|
|
|
NS_PRECONDITION(nsnull != aPresContext, "nsnull ptr");
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
if (nsnull != shell) {
|
|
|
|
shell->FlushPendingNotifications();
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
2001-02-19 12:55:42 +00:00
|
|
|
shell->GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
if (viewManager) {
|
2001-01-20 04:59:39 +00:00
|
|
|
viewManager->FlushPendingInvalidates();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-06-23 21:53:02 +00:00
|
|
|
nsresult NS_NewEventStateManager(nsIEventStateManager** aInstancePtrResult)
|
|
|
|
{
|
2000-03-15 04:03:44 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
1998-06-23 21:53:02 +00:00
|
|
|
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;
|
|
|
|
}
|
2000-03-15 04:03:44 +00:00
|
|
|
rv = manager->QueryInterface(NS_GET_IID(nsIEventStateManager),
|
2000-02-05 00:58:29 +00:00
|
|
|
(void **) aInstancePtrResult);
|
2000-03-15 04:03:44 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return manager->Init();
|
1998-06-23 21:53:02 +00:00
|
|
|
}
|
|
|
|
|
2001-02-15 05:07:46 +00:00
|
|
|
|
|
|
|
nsresult nsEventStateManager::GetCaretLocation(nsIContent **aCaretContent,
|
|
|
|
nsIFrame **aCaretFrame, PRUint32* aCaretOffset)
|
|
|
|
{
|
|
|
|
// In order to return the nsIContent and nsIFrame of the caret's position,
|
|
|
|
// we need to get a pres shell, and then get the selection from it
|
|
|
|
|
|
|
|
*aCaretFrame = nsnull;
|
|
|
|
*aCaretContent = nsnull;
|
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
if (mPresContext)
|
|
|
|
rv = mPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFrameSelection> selectionFrame;
|
|
|
|
if (shell)
|
|
|
|
rv = shell->GetFrameSelection(getter_AddRefs(selectionFrame));
|
|
|
|
|
|
|
|
nsCOMPtr<nsISelection> domSelection;
|
|
|
|
if (selectionFrame)
|
|
|
|
rv = selectionFrame->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
|
|
|
getter_AddRefs(domSelection));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNode> focusDomNode;
|
|
|
|
if (domSelection) {
|
|
|
|
rv = domSelection->GetAnchorNode(getter_AddRefs(focusDomNode));
|
|
|
|
typedef PRInt32* PRInt32_ptr;
|
|
|
|
domSelection->GetAnchorOffset(PRInt32_ptr(aCaretOffset));
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> selectionContent(do_QueryInterface(focusDomNode));
|
|
|
|
|
|
|
|
nsIFrame *primaryFrame = nsnull;
|
|
|
|
if (selectionContent)
|
|
|
|
rv = shell->GetPrimaryFrameFor(selectionContent, &primaryFrame);
|
|
|
|
|
|
|
|
*aCaretFrame = primaryFrame;
|
|
|
|
*aCaretContent = selectionContent;
|
|
|
|
NS_ADDREF(*aCaretContent);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult nsEventStateManager::MoveFocusToCaret()
|
|
|
|
{
|
|
|
|
// mBrowseWithCaret equals the pref accessibility.browsewithcaret
|
|
|
|
// When it's true, the user can arrow around the browser as if it's a
|
|
|
|
// read only text editor.
|
|
|
|
// If they cursor over a focusable element, then send focus to it
|
|
|
|
nsCOMPtr<nsIContent> caretContent;
|
|
|
|
nsIFrame *caretFrame;
|
|
|
|
PRUint32 caretOffset;
|
|
|
|
nsresult rv = GetCaretLocation(getter_AddRefs(caretContent),
|
|
|
|
&caretFrame, &caretOffset);
|
|
|
|
|
|
|
|
if (caretContent) {
|
|
|
|
// First check to see if our caret is at the very end of a node
|
|
|
|
// If so, the caret is actually sitting in front of the next
|
|
|
|
// logical frame's primary node - so for this case we need to
|
|
|
|
// change caretContent to that node.
|
|
|
|
nsCOMPtr<nsIContent> origCaretContent(caretContent);
|
|
|
|
nsAutoString nodeValue;
|
|
|
|
nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(caretContent));
|
|
|
|
domNode->GetNodeValue(nodeValue);
|
|
|
|
|
|
|
|
if (nodeValue.Length() == caretOffset) {
|
|
|
|
// Yes, indeed we were at the end of the last node
|
|
|
|
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
|
2001-02-19 14:19:42 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,
|
|
|
|
&rv));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
rv = trav->NewFrameTraversal(getter_AddRefs(frameTraversal), EXTENSIVE,
|
|
|
|
mPresContext, caretFrame);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2001-02-15 05:07:46 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
// Get the next logical frame, and set the start of
|
|
|
|
// focusable elements. Search for focusable elements from there.
|
|
|
|
// Continue getting next frame until the primary node for the frame
|
|
|
|
// we are on changes - we don't want to be stuck in the same place
|
|
|
|
frameTraversal->Next();
|
|
|
|
nsISupports* currentItem;
|
|
|
|
frameTraversal->CurrentItem(¤tItem);
|
|
|
|
caretFrame = NS_STATIC_CAST(nsIFrame*, currentItem);
|
|
|
|
if (caretFrame)
|
|
|
|
caretFrame->GetContent(getter_AddRefs(caretContent));
|
|
|
|
else break;
|
|
|
|
}
|
|
|
|
while (caretContent && caretContent == origCaretContent);
|
|
|
|
}
|
|
|
|
|
|
|
|
// We now have the correct start node in caretContent!
|
|
|
|
// Search for focusable elements, starting with caretContent
|
|
|
|
// Keep going up while we look - an ancestory might be focusable
|
|
|
|
|
|
|
|
// jst: We could end the loop earlier, such as when we're no longer
|
|
|
|
// in the same frame, by comparing getPrimaryFrameFor(caretContent)
|
|
|
|
// with a variable holding the starting caretContent
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
while (caretContent && NS_SUCCEEDED(rv)) {
|
|
|
|
// Keep testing while caretContent is equal to something,
|
|
|
|
// eventually we'll run out of ancestors
|
|
|
|
|
|
|
|
domNode = do_QueryInterface(caretContent);
|
|
|
|
if (!domNode)
|
|
|
|
break;
|
|
|
|
|
|
|
|
domNode->GetNodeValue(nodeValue);
|
|
|
|
caretContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (caretContent.get() == mCurrentFocus)
|
|
|
|
break; // already focused on this node, this whole thing's moot
|
|
|
|
|
|
|
|
// For now, all we're going to focus on during this move by
|
|
|
|
// cursor is ordinary links
|
|
|
|
// Add more focusable tags here later if necessary ...
|
|
|
|
if (nsHTMLAtoms::a == tag.get()) {
|
|
|
|
// We are on a link, so change focus to it.
|
|
|
|
ChangeFocus(caretContent, caretFrame, PR_TRUE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Get the parent
|
|
|
|
nsIContent* parent;
|
|
|
|
caretContent->GetParent(parent);
|
|
|
|
caretContent = dont_AddRef(parent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult nsEventStateManager::MoveCaretToFocus()
|
|
|
|
{
|
|
|
|
// If in HTML content and the pref accessibility.browsewithcaret is TRUE,
|
|
|
|
// then always move the caret to beginning of a new focus
|
|
|
|
|
|
|
|
if (mBrowseWithCaret && mPresContext) {
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
mPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
if (shell) {
|
|
|
|
// rangeDoc is a document interface we can create a range with
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsCOMPtr<nsIDOMDocumentRange> rangeDoc(do_QueryInterface(mDocument));
|
2001-02-15 05:07:46 +00:00
|
|
|
nsCOMPtr<nsIDOMNode> currentFocusNode(do_QueryInterface(mCurrentFocus));
|
|
|
|
nsCOMPtr<nsIFrameSelection> frameSelection;
|
|
|
|
shell->GetFrameSelection(getter_AddRefs(frameSelection));
|
|
|
|
nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(currentFocusNode));
|
|
|
|
|
|
|
|
if (frameSelection && currentFocusNode && rangeDoc && !formControl) {
|
|
|
|
nsCOMPtr<nsISelection> domSelection;
|
|
|
|
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
|
|
|
getter_AddRefs(domSelection));
|
|
|
|
if (domSelection) {
|
|
|
|
// First clear the selection
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
domSelection->RemoveAllRanges();
|
2001-02-15 05:07:46 +00:00
|
|
|
nsCOMPtr<nsIDOMRange> newRange;
|
|
|
|
nsresult rv = rangeDoc->CreateRange(getter_AddRefs(newRange));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// If we could create a new range, then set it to the current focus node
|
|
|
|
// And then collapse the selection
|
|
|
|
newRange->SelectNodeContents(currentFocusNode);
|
|
|
|
domSelection->AddRange(newRange);
|
|
|
|
domSelection->CollapseToStart();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult nsEventStateManager::EnsureCaretVisible(nsIPresShell* aPresShell, nsIContent *aContent)
|
|
|
|
{
|
|
|
|
// When browsing with caret, make sure caret is visible after new focus
|
|
|
|
nsCOMPtr<nsIFrameSelection> frameSelection;
|
|
|
|
aPresShell->GetFrameSelection(getter_AddRefs(frameSelection));
|
|
|
|
nsCOMPtr<nsICaret> caret;
|
|
|
|
aPresShell->GetCaret(getter_AddRefs(caret));
|
|
|
|
|
|
|
|
if (frameSelection && caret) {
|
|
|
|
nsCOMPtr<nsISelection> domSelection;
|
|
|
|
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
|
|
|
getter_AddRefs(domSelection));
|
|
|
|
|
|
|
|
if (domSelection) {
|
|
|
|
nsCOMPtr<nsIDOMNode> focusDomNode;
|
|
|
|
domSelection->GetAnchorNode(getter_AddRefs(focusDomNode));
|
|
|
|
// first, tell the caret which selection to use
|
|
|
|
if (!aContent) {
|
|
|
|
caret->SetCaretDOMSelection(domSelection);
|
|
|
|
// otherwise, aContent == nsnull, so item is focusable
|
|
|
|
// in that case, let focus handlers take care of setting the caret's dom selection
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsISelectionController> selCon(do_QueryInterface(aPresShell));
|
|
|
|
if (!selCon)
|
|
|
|
return NS_ERROR_NO_INTERFACE;
|
|
|
|
selCon->SetCaretEnabled(PR_TRUE);
|
|
|
|
caret->SetCaretVisible(PR_TRUE);
|
|
|
|
|
|
|
|
PRInt32 pixelWidth = 1;
|
|
|
|
nsCOMPtr<nsILookAndFeel> lookNFeel(do_GetService(kLookAndFeelCID));
|
|
|
|
if (lookNFeel)
|
|
|
|
lookNFeel->GetMetric(nsILookAndFeel::eMetric_MultiLineCaretWidth, pixelWidth);
|
|
|
|
caret->SetCaretWidth(pixelWidth);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-05-22 23:52:17 +00:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
//-- DocShell Focus Traversal Methods
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
// Returns PR_TRUE if this doc contains a frameset
|
|
|
|
PRBool
|
|
|
|
nsEventStateManager::IsFrameSetDoc(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aContent, "Pointer is null!");
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLFrameSetElement> frameSet = do_QueryInterface(aContent);
|
|
|
|
if (frameSet) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 count;
|
|
|
|
aContent->ChildCount(count);
|
|
|
|
for (PRInt32 i=0;i<count;i++) {
|
|
|
|
nsIContent* child;
|
|
|
|
aContent->ChildAt(i, child);
|
|
|
|
if (IsFrameSetDoc(child)) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
// This method finds the content node in the parent document
|
|
|
|
// corresponds to the docshell
|
|
|
|
nsIContent*
|
|
|
|
nsEventStateManager::FindContentForDocShell(nsIPresShell* aPresShell,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIDocShell* aDocShell)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aPresShell, "Pointer is null!");
|
|
|
|
NS_ASSERTION(aDocShell, "Pointer is null!");
|
|
|
|
NS_ASSERTION(aContent, "Pointer is null!");
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> supps;
|
|
|
|
aPresShell->GetSubShellFor(aContent, getter_AddRefs(supps));
|
|
|
|
if (supps) {
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(supps));
|
|
|
|
if (docShell.get() == aDocShell) {
|
|
|
|
NS_ADDREF(aContent);
|
|
|
|
return aContent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// walk children content
|
|
|
|
PRInt32 count;
|
|
|
|
aContent->ChildCount(count);
|
|
|
|
for (PRInt32 i=0;i<count;i++) {
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
aContent->ChildAt(i, *getter_AddRefs(child));
|
|
|
|
nsIContent* foundContent = FindContentForDocShell(aPresShell, child, aDocShell);
|
|
|
|
if (foundContent != nsnull) {
|
|
|
|
return foundContent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
// This method checks to see if the Content node
|
|
|
|
// (that is a HTMLFrame, is the last one
|
|
|
|
PRBool
|
|
|
|
nsEventStateManager::IsLastFrameInFrameSet(nsIContent* aLastFrameContent)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aLastFrameContent, "Pointer is null!");
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> parent;
|
|
|
|
aLastFrameContent->GetParent(*getter_AddRefs(parent));
|
|
|
|
NS_ASSERTION(parent, "parent is null!");
|
|
|
|
|
|
|
|
PRInt32 count;
|
|
|
|
parent->ChildCount(count);
|
|
|
|
for (PRInt32 i=0;i<count;i++) {
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
parent->ChildAt(i, *getter_AddRefs(child));
|
|
|
|
if (child.get() == aLastFrameContent && i == count-1) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
// Identifies the type of document it is
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEventStateManager::FigureOutKindOfDoc(nsIDocument* aDoc, eDocType* aDocType)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aDoc);
|
|
|
|
NS_ENSURE_ARG_POINTER(aDocType);
|
|
|
|
|
|
|
|
*aDocType = eChrome;
|
|
|
|
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aDoc->GetShellAt(0, getter_AddRefs(presShell));
|
2001-05-22 23:52:17 +00:00
|
|
|
if (!presShell) return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
presShell->GetPresContext(getter_AddRefs(presContext));
|
|
|
|
if (!presContext) return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsISupports> pcContainer;
|
|
|
|
presContext->GetContainer(getter_AddRefs(pcContainer));
|
|
|
|
if (!pcContainer) return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(pcContainer));
|
|
|
|
|
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
printf("FigureOutKindOfDoc DocShell %p Doc: %p\n", docShell.get(), aDoc);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Make sure this document is "content" and not "chrome"
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(docShell));
|
|
|
|
if (!treeItem) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
PRInt32 type;
|
|
|
|
treeItem->GetItemType(&type);
|
|
|
|
if (type != nsIDocShellTreeItem::typeContent) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
*aDocType = eGenericContent;
|
|
|
|
|
|
|
|
// See if we are a frame set
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIContent> rootContent;
|
|
|
|
aDoc->GetRootContent(getter_AddRefs(rootContent));
|
2001-05-22 23:52:17 +00:00
|
|
|
if (IsFrameSetDoc(rootContent)) {
|
|
|
|
*aDocType = eFrameSet;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// So we know we the docShell is content and it isn't
|
|
|
|
// a FrameSet, so let's get the parent's doc to see if we
|
|
|
|
// are a FrameSet-Frame or an IFrame
|
|
|
|
|
|
|
|
// Get Parent Doc
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> treeItemParent;
|
|
|
|
treeItem->GetParent(getter_AddRefs(treeItemParent));
|
|
|
|
if (!treeItemParent) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> parentDS = do_QueryInterface(treeItemParent);
|
|
|
|
if (!parentDS) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> parentPresShell;
|
|
|
|
parentDS->GetPresShell(getter_AddRefs(parentPresShell));
|
|
|
|
if (!parentPresShell) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> parentDoc;
|
|
|
|
parentPresShell->GetDocument(getter_AddRefs(parentDoc));
|
|
|
|
if (!parentDoc) return NS_ERROR_FAILURE;
|
|
|
|
|
2001-06-20 03:27:48 +00:00
|
|
|
parentDoc->GetRootContent(getter_AddRefs(rootContent));
|
2001-05-22 23:52:17 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> content = getter_AddRefs(FindContentForDocShell(parentPresShell, rootContent, docShell));
|
|
|
|
|
|
|
|
// Is it a FrameSet Frame?
|
|
|
|
nsCOMPtr<nsIDOMHTMLFrameElement> frameSetFrame = do_QueryInterface(content);
|
|
|
|
if (frameSetFrame) {
|
|
|
|
*aDocType = eFrame;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Is it an IFrame/
|
|
|
|
nsCOMPtr<nsIDOMHTMLIFrameElement> iframe = do_QueryInterface(content);
|
|
|
|
if (iframe) {
|
|
|
|
*aDocType = eIFrame;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
// Generic Content gets here
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
// This method gets the DocShells for the document and
|
|
|
|
// its parent
|
|
|
|
nsresult
|
|
|
|
nsEventStateManager::GetDocShellsFromDoc(nsIDocument* aDocument,
|
|
|
|
nsIDocShell** aDocShell,
|
|
|
|
nsIDocShell** aParentDS)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aDocument, "Pointer is null!");
|
|
|
|
NS_ASSERTION(aDocShell, "Pointer is null!");
|
|
|
|
NS_ASSERTION(aParentDS, "Pointer is null!");
|
|
|
|
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aDocument->GetShellAt(0, getter_AddRefs(presShell));
|
2001-05-22 23:52:17 +00:00
|
|
|
if (!presShell) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
presShell->GetPresContext(getter_AddRefs(presContext));
|
|
|
|
if (!presContext) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> pcContainer;
|
|
|
|
presContext->GetContainer(getter_AddRefs(pcContainer));
|
|
|
|
if (!pcContainer) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> docshell(do_QueryInterface(pcContainer));
|
|
|
|
if (!docshell) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
*aDocShell = docshell.get();
|
|
|
|
NS_ADDREF(*aDocShell);
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(docshell));
|
|
|
|
if (!treeItem) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> treeItemParent;
|
|
|
|
treeItem->GetParent(getter_AddRefs(treeItemParent));
|
|
|
|
if (!treeItemParent) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> parentDS(do_QueryInterface(treeItemParent));
|
|
|
|
if (!parentDS) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
*aParentDS = parentDS.get();
|
|
|
|
NS_ADDREF(*aParentDS);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
// This method refreshes a docshell
|
|
|
|
void
|
|
|
|
nsEventStateManager::ForceUpdate(nsIDocShell* aDocShell)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aDocShell, "Pointer is null!");
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aDocShell->GetPresShell(getter_AddRefs(presShell));
|
|
|
|
if (!presShell) return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
aDocShell->GetPresContext(getter_AddRefs(presContext));
|
|
|
|
if (!presContext) return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIViewManager> vm;
|
|
|
|
presShell->GetViewManager(getter_AddRefs(vm));
|
|
|
|
if (!vm) return;
|
|
|
|
|
|
|
|
vm->UpdateAllViews(NS_VMREFRESH_NO_SYNC);
|
|
|
|
|
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
printf("ForceUpdate - DS: %p ********************************************\n", aDocShell);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
// This method will find the next DocShell within Parent
|
|
|
|
nsIDocShell*
|
|
|
|
nsEventStateManager::GetNextDocShell(nsIDocShell* aParentDS, nsIDocShell* aCurrentDS, PRBool aForward)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aParentDS, "Pointer is null!");
|
|
|
|
NS_ASSERTION(aCurrentDS, "Pointer is null!");
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> parentTreeNode(do_QueryInterface(aParentDS));
|
|
|
|
if (!parentTreeNode) return nsnull;
|
|
|
|
|
|
|
|
PRInt32 count;
|
|
|
|
parentTreeNode->GetChildCount(&count);
|
|
|
|
for (PRInt32 i=0;i<count;i++) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> child;
|
|
|
|
parentTreeNode->GetChildAt(i, getter_AddRefs(child));
|
|
|
|
nsCOMPtr<nsIDocShell> ds = do_QueryInterface(child);
|
|
|
|
if (ds.get() == aCurrentDS) {
|
|
|
|
i += aForward?1:-1;
|
|
|
|
if (i > -1 && i < count) {
|
|
|
|
parentTreeNode->GetChildAt(i, getter_AddRefs(child));
|
|
|
|
ds = do_QueryInterface(child);
|
|
|
|
nsIDocShell* fndDocShell = ds.get();
|
|
|
|
NS_ADDREF(fndDocShell);
|
|
|
|
return fndDocShell;
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
// This method will find a DocShell that corresponds to
|
|
|
|
// a content node in a parent document
|
|
|
|
nsIDocShell*
|
|
|
|
nsEventStateManager::GetDocShellFromContent(nsIDocShell* aParentDocShell, nsIContent* aContent)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aParentDocShell, "Pointer is null!");
|
|
|
|
NS_ASSERTION(aContent, "Pointer is null!");
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> parentPresShell;
|
|
|
|
aParentDocShell->GetPresShell(getter_AddRefs(parentPresShell));
|
|
|
|
nsCOMPtr<nsISupports> supports;
|
|
|
|
parentPresShell->GetSubShellFor(aContent, getter_AddRefs(supports));
|
|
|
|
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(supports);
|
|
|
|
if (docShell) {
|
|
|
|
nsIDocShell* ds = docShell.get();
|
|
|
|
NS_ADDREF(ds);
|
|
|
|
return ds;
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
// This method will get the very last content object
|
|
|
|
// when given aRootContent node
|
|
|
|
nsIContent*
|
|
|
|
nsEventStateManager::GetLastContent(nsIContent* aRootContent)
|
|
|
|
{
|
|
|
|
if (aRootContent == nsnull) {
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 count;
|
|
|
|
aRootContent->ChildCount(count);
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
aRootContent->ChildAt(count-1, *getter_AddRefs(child));
|
|
|
|
nsIContent* last = GetLastContent(child);
|
|
|
|
return last;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
// This method will get the very last content object in
|
|
|
|
// in a DocShell
|
|
|
|
nsIContent*
|
|
|
|
nsEventStateManager::GetLastContent(nsIDocShell* aDocShell)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aDocShell, "Pointer is null!");
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aDocShell->GetPresShell(getter_AddRefs(presShell));
|
|
|
|
if (!presShell) return nsnull;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
presShell->GetDocument(getter_AddRefs(doc));
|
|
|
|
if (!doc) return nsnull;
|
|
|
|
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIContent> rootContent;
|
|
|
|
doc->GetRootContent(getter_AddRefs(rootContent));
|
2001-05-22 23:52:17 +00:00
|
|
|
if (!rootContent) return nsnull;
|
|
|
|
|
|
|
|
nsIContent* last = nsnull;
|
|
|
|
nsCOMPtr<nsIContent> parent = rootContent;
|
|
|
|
PRInt32 count;
|
|
|
|
parent->ChildCount(count);
|
|
|
|
while (count > 0) {
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
parent->ChildAt(count-1, *getter_AddRefs(child));
|
|
|
|
child->ChildCount(count);
|
|
|
|
parent = child;
|
|
|
|
last = child.get();
|
|
|
|
}
|
|
|
|
NS_IF_ADDREF(last);
|
|
|
|
return last;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
// This method will get the "next" Frame in a FrameSet (forward or backwards)
|
|
|
|
// and if one doesn't exist, then focus the next docshell AFTER
|
|
|
|
// the FrameSet
|
|
|
|
PRBool
|
|
|
|
nsEventStateManager::FocusAfterHTMLFrameDoc(nsIDocShell* aDocShell,
|
|
|
|
nsIDocShell* aParentDocShell,
|
|
|
|
PRBool aForward)
|
|
|
|
{
|
|
|
|
// neither of should ever be null, but just in case
|
|
|
|
if (aDocShell == nsnull || aParentDocShell == nsnull) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to get the next DocShell
|
|
|
|
nsCOMPtr<nsIDocShell> nextDocShell = getter_AddRefs(GetNextDocShell(aParentDocShell, aDocShell, aForward));
|
|
|
|
if (nextDocShell) {
|
|
|
|
// unset focus in current doc
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(nextDocShell));
|
|
|
|
if (NS_SUCCEEDED(baseWin->SetFocus())) {
|
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
printf("Focused DS: %p ********************************************\n", nextDocShell.get());
|
|
|
|
#endif
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// ok, since the we are a HTMLFrame and parent is a FrameSet
|
|
|
|
// then we will get the parent of the FrameSet and try to
|
|
|
|
// find the next aDocShell
|
|
|
|
nsCOMPtr<nsIDocShell> oldDocShell = aDocShell;
|
|
|
|
|
|
|
|
// unset focus in current doc
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentItem(do_QueryInterface(aParentDocShell));
|
|
|
|
if (!parentItem) return PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> ds = aDocShell;
|
|
|
|
nsCOMPtr<nsIDocShell> pDS = aParentDocShell;
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentParentItem;
|
|
|
|
parentItem->GetParent(getter_AddRefs(parentParentItem));
|
|
|
|
if (parentParentItem) {
|
|
|
|
ds = aParentDocShell;
|
|
|
|
pDS = do_QueryInterface(parentParentItem);
|
|
|
|
}
|
|
|
|
PRBool focusTaken;
|
|
|
|
// it was the last one in the Frame
|
|
|
|
//Offer focus upwards to allow shifting focus to UI controls
|
|
|
|
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(ds));
|
|
|
|
nsCOMPtr<nsIBaseWindow> parentDocShellAsWin(do_QueryInterface(pDS));
|
|
|
|
if (docShellAsWin && parentDocShellAsWin) {
|
|
|
|
parentDocShellAsWin->FocusAvailable(docShellAsWin, aForward, &focusTaken);
|
|
|
|
if (focusTaken) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
// This methods finds the content object in the parent document that
|
|
|
|
// corresponds to the aDocShell.
|
|
|
|
// Then the parent doc is asked to find the next "focusable" item
|
|
|
|
// AFTER this IFrame.
|
|
|
|
PRBool
|
|
|
|
nsEventStateManager::FocusAfterHTMLIFrameDoc(nsIDocShell* aDocShell,
|
|
|
|
nsIDocShell* aParentDocShell,
|
|
|
|
PRBool aForward,
|
|
|
|
PRBool& aFocusDoc)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aDocShell, "Pointer is null!");
|
|
|
|
NS_ASSERTION(aParentDocShell, "Pointer is null!");
|
|
|
|
|
|
|
|
// Make sure this IFrame is inside a Content Doc
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentItem(do_QueryInterface(aParentDocShell));
|
|
|
|
if (!parentItem) return PR_FALSE;
|
|
|
|
|
|
|
|
PRInt32 type;
|
|
|
|
parentItem->GetItemType(&type);
|
|
|
|
if (type == nsIDocShellTreeItem::typeContent) {
|
|
|
|
|
|
|
|
// remove focus from any items in doc
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
|
|
|
|
|
|
|
// Go find the root content object for the parent document
|
|
|
|
// so we can find the content that corresponds to this docshell
|
|
|
|
nsCOMPtr<nsIPresShell> parentPresShell;
|
|
|
|
aParentDocShell->GetPresShell(getter_AddRefs(parentPresShell));
|
|
|
|
if (!parentPresShell) return PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> parentDoc;
|
|
|
|
parentPresShell->GetDocument(getter_AddRefs(parentDoc));
|
|
|
|
if (!parentDoc) return PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresContext> parentPresContext;
|
|
|
|
aParentDocShell->GetPresContext(getter_AddRefs(parentPresContext));
|
|
|
|
if (!parentPresContext) return PR_FALSE;
|
|
|
|
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIContent> rootContent;
|
|
|
|
parentDoc->GetRootContent(getter_AddRefs(rootContent));
|
2001-05-22 23:52:17 +00:00
|
|
|
if (!rootContent) return PR_FALSE;
|
|
|
|
|
|
|
|
// Now that we have the Root Content for the Parent Doc
|
|
|
|
// we can look for the the content object that corresponds to this DocShell
|
|
|
|
nsCOMPtr<nsIContent> focusedContent = getter_AddRefs(FindContentForDocShell(parentPresShell, rootContent, aDocShell));
|
|
|
|
|
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
printf("For Child DocShell %p shifting focus to content %p in parent DocShell %p\n",
|
|
|
|
aDocShell, focusedContent.get(), aParentDocShell);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
nsCOMPtr<nsIEventStateManager> esm;
|
|
|
|
parentPresContext->GetEventStateManager(getter_AddRefs(esm));
|
|
|
|
if (!esm) return PR_FALSE;
|
|
|
|
|
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
printf("PDS: %p Pres %p EM %p Doc %p\n", aParentDocShell,
|
|
|
|
parentPresShell.get(), esm.get(), parentDoc.get());
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// So we use that Content node in the Parent Doc
|
|
|
|
// to focus the very next object
|
|
|
|
if (focusedContent) {
|
|
|
|
esm->MoveFocus(aForward, focusedContent);
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIContent> newFocusedContent;
|
|
|
|
esm->GetFocusedContent(getter_AddRefs(newFocusedContent));
|
|
|
|
|
|
|
|
/*nsCOMPtr<nsIContent> next;
|
|
|
|
nsIFrame* primaryFrame = nsnull;
|
|
|
|
parentPresShell->GetPrimaryFrameFor(focusedContent, &primaryFrame);
|
|
|
|
if (primaryFrame) {
|
|
|
|
esm->GetNextTabbableContent(rootContent, primaryFrame, aForward, getter_AddRefs(next));
|
|
|
|
}*/
|
|
|
|
|
|
|
|
if (newFocusedContent) {
|
|
|
|
// Now, give focus to the DOM Window
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> sgo;
|
|
|
|
parentDoc->GetScriptGlobalObject(getter_AddRefs(sgo));
|
|
|
|
if (!sgo) return PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMWindowInternal> domwin(do_QueryInterface(sgo));
|
|
|
|
if (domwin && NS_SUCCEEDED(domwin->Focus())) {
|
|
|
|
aParentDocShell->SetCanvasHasFocus(PR_FALSE);
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tell the outside NOT to focus the document
|
|
|
|
// because it found something to focus
|
|
|
|
aFocusDoc = PR_FALSE;
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// This method is checking for two things:
|
|
|
|
//
|
|
|
|
// 1) To see if the currently focused content has a docshell
|
|
|
|
// and if it does we focus it
|
|
|
|
//
|
|
|
|
// 2) Check to see if this frame is the last frame in the frameset
|
|
|
|
// and if it is then we want the parent to focus the next piece of
|
|
|
|
// content, which means it should move on to the Chrome
|
|
|
|
PRBool
|
|
|
|
nsEventStateManager::FocusWithinHTMLFrameDoc(nsIContent* aRootContent,
|
|
|
|
nsIPresShell* aPresShell,
|
|
|
|
PRBool aForward,
|
|
|
|
PRBool& aDoFocusAvailDocShells)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aPresShell, "Pointer is null!");
|
|
|
|
|
|
|
|
if (mCurrentFocus == nsnull) return PR_FALSE;
|
|
|
|
|
|
|
|
if (aRootContent == nsnull) {
|
|
|
|
if (aPresShell) {
|
|
|
|
// See if the currently focused item has a DocShell (like an IFrame)
|
|
|
|
// and then give it focus
|
|
|
|
nsCOMPtr<nsISupports> supports;
|
|
|
|
aPresShell->GetSubShellFor(mCurrentFocus, getter_AddRefs(supports));
|
|
|
|
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(supports);
|
|
|
|
if (docShell) {
|
|
|
|
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(docShell));
|
|
|
|
if (NS_SUCCEEDED(baseWin->SetFocus())) {
|
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
printf("Focused DS: %p ********************************************\n", docShell.get());
|
|
|
|
#endif
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Ok, the root content has been set so we need to go find the content
|
|
|
|
// in the parent's doc that represents this DocShell
|
|
|
|
nsCOMPtr<nsIDocShell> docShell;
|
|
|
|
nsCOMPtr<nsIDocShell> parentDS;
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(GetDocShellsFromDoc(mDocument, getter_AddRefs(docShell), getter_AddRefs(parentDS)))) {
|
|
|
|
nsCOMPtr<nsIPresShell> parentPresShell;
|
|
|
|
parentDS->GetPresShell(getter_AddRefs(parentPresShell));
|
|
|
|
if (!parentPresShell) return PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> parentDoc;
|
|
|
|
parentPresShell->GetDocument(getter_AddRefs(parentDoc));
|
|
|
|
if (!parentDoc) return PR_FALSE;
|
|
|
|
|
2001-06-20 03:27:48 +00:00
|
|
|
nsCOMPtr<nsIContent> rootContent;
|
|
|
|
parentDoc->GetRootContent(getter_AddRefs(rootContent));
|
2001-05-22 23:52:17 +00:00
|
|
|
if (!rootContent) return PR_FALSE;
|
|
|
|
|
|
|
|
// Look up the content
|
|
|
|
nsCOMPtr<nsIContent> focusedContent = getter_AddRefs(FindContentForDocShell(parentPresShell, rootContent, docShell));
|
|
|
|
|
|
|
|
// Now check to see if the focused piece of content that represents
|
|
|
|
// the current DocShell is the last frame in the frameset
|
|
|
|
if (focusedContent && IsLastFrameInFrameSet(focusedContent)) {
|
|
|
|
aDoFocusAvailDocShells = PR_TRUE;
|
|
|
|
|
|
|
|
PRBool focusTaken = PR_FALSE;
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
|
|
|
|
|
|
|
// Now let the parent doc find the next focusable DocShell
|
|
|
|
// and in this case the focus will move on out of the frameset
|
|
|
|
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(docShell));
|
|
|
|
nsCOMPtr<nsIBaseWindow> parentDocShellAsWin(do_QueryInterface(parentDS));
|
|
|
|
if (docShellAsWin) {
|
|
|
|
parentDocShellAsWin->FocusAvailable(docShellAsWin, aForward, &focusTaken);
|
|
|
|
if (focusTaken) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// This method finds the
|
|
|
|
PRBool
|
|
|
|
nsEventStateManager::FocusWithinHTMLIFrameDoc(nsIContent* aNextContent, PRBool aForward)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aNextContent, "Pointer is null!");
|
|
|
|
|
|
|
|
// Begin by finding the DocShell for this document
|
|
|
|
// and the DocShell for the IFrame content
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
mPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
|
|
|
|
if (!docShell) return PR_FALSE;
|
|
|
|
|
|
|
|
// Here we find the DocShell that correpsonds to the IFrame
|
|
|
|
nsCOMPtr<nsIDocShell> newDocShell = getter_AddRefs(GetDocShellFromContent(docShell, aNextContent));
|
|
|
|
if (newDocShell) {
|
|
|
|
nsCOMPtr<nsIBaseWindow> newDocShellAsWin(do_QueryInterface(newDocShell));
|
|
|
|
if (newDocShellAsWin) {
|
|
|
|
// Clear focus in current document
|
|
|
|
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
|
|
|
|
|
|
|
// set focus in IFrame
|
|
|
|
if (NS_SUCCEEDED(newDocShellAsWin->SetFocus())) {
|
|
|
|
// Now if we are reversing through the document then
|
|
|
|
// we need to find the last piece of content in the IFrame document
|
|
|
|
if (!aForward) {
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
newDocShell->GetPresContext(getter_AddRefs(presContext));
|
|
|
|
if (!presContext) return PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIEventStateManager> esm;
|
|
|
|
presContext->GetEventStateManager(getter_AddRefs(esm));
|
|
|
|
if (!esm) return PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> lastContent = getter_AddRefs(GetLastContent(newDocShell));
|
|
|
|
if (lastContent) {
|
|
|
|
esm->MoveFocus(PR_FALSE, lastContent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------
|
|
|
|
// Traversal by document/DocShell only
|
|
|
|
// this does not inclide any content inside the doc
|
|
|
|
// or IFrames
|
|
|
|
void
|
|
|
|
nsEventStateManager::ShiftFocusByDoc(PRBool aForward, nsIContent* aRoot)
|
|
|
|
{
|
|
|
|
// Figure out what type of document we are
|
|
|
|
eDocType docType;
|
|
|
|
FigureOutKindOfDoc(mDocument, &docType);
|
|
|
|
|
|
|
|
#ifdef DEBUG_DOCSHELL_FOCUS
|
|
|
|
printf("Doc Type is [%s]\n", gDocTypeNames[docType]);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (docType == eChrome) {
|
|
|
|
ShiftFocus(aForward, aRoot);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (docType == eFrame) {
|
|
|
|
nsCOMPtr<nsIDocShell> docShell;
|
|
|
|
nsCOMPtr<nsIDocShell> parentDS;
|
|
|
|
if (NS_SUCCEEDED(GetDocShellsFromDoc(mDocument, getter_AddRefs(docShell), getter_AddRefs(parentDS)))) {
|
|
|
|
// Try to focus the Next Frame in the FrameSet
|
|
|
|
// if there is none then focus the next Chrome Doc
|
|
|
|
FocusAfterHTMLFrameDoc(docShell, parentDS, aForward);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|