276 lines
8.7 KiB
C++
Executable File
276 lines
8.7 KiB
C++
Executable File
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla 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/MPL/
|
|
*
|
|
* 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.
|
|
*
|
|
* The Original Code is Spatial Navigation
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Douglas F. Turner II <dougt@meer.net>
|
|
* Portions created by the Initial Developer are Copyright (C) 2004-2005
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "memory.h"
|
|
#include "stdlib.h"
|
|
|
|
#include "nspr.h"
|
|
|
|
#include "nsXPCOM.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsMemory.h"
|
|
#include "nsString.h"
|
|
|
|
#include "nsISpatialNavigation.h"
|
|
|
|
#include "nsDirectoryServiceDefs.h"
|
|
#include "nsDirectoryServiceUtils.h"
|
|
#include "nsFrameTraversal.h"
|
|
#include "nsIArray.h"
|
|
#include "nsIBaseWindow.h"
|
|
#include "nsICategoryManager.h"
|
|
#include "nsIComponentManager.h"
|
|
#include "nsIDOM3EventTarget.h"
|
|
#include "nsIDOMAbstractView.h"
|
|
#include "nsIDOMCSSStyleDeclaration.h"
|
|
#include "nsIDOMDocument.h"
|
|
#include "nsIDOMDocument.h"
|
|
#include "nsIDOMDocumentView.h"
|
|
#include "nsIDOMElementCSSInlineStyle.h"
|
|
#include "nsIDOMEvent.h"
|
|
#include "nsIDOMEventGroup.h"
|
|
#include "nsIDOMEventTarget.h"
|
|
#include "nsIDOMHTMLAnchorElement.h"
|
|
#include "nsIDOMHTMLAreaElement.h"
|
|
#include "nsIDOMHTMLCollection.h"
|
|
#include "nsIDOMHTMLDocument.h"
|
|
#include "nsIDOMHTMLFrameElement.h"
|
|
#include "nsIDOMHTMLHtmlElement.h"
|
|
#include "nsIDOMHTMLIFrameElement.h"
|
|
#include "nsIDOMHTMLInputElement.h"
|
|
#include "nsIDOMHTMLMapElement.h"
|
|
#include "nsIDOMHTMLOptionElement.h"
|
|
#include "nsIDOMHTMLSelectElement.h"
|
|
#include "nsIDOMKeyEvent.h"
|
|
#include "nsIDOMKeyListener.h"
|
|
#include "nsIDOMNSEvent.h"
|
|
#include "nsIDOMNSHTMLElement.h"
|
|
#include "nsIDOMNSUIEvent.h"
|
|
#include "nsIDOMNSHTMLInputElement.h"
|
|
#include "nsIDOMNSHTMLTextAreaElement.h"
|
|
#include "nsIDOMNode.h"
|
|
#include "nsIDOMWindow.h"
|
|
#include "nsIDOMWindowInternal.h"
|
|
#include "nsIDocShell.h"
|
|
#include "nsIDocShellTreeItem.h"
|
|
#include "nsIDocShellTreeOwner.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsIDocumentViewer.h"
|
|
#include "nsIEventStateManager.h"
|
|
#include "nsIFile.h"
|
|
#include "nsIFocusController.h"
|
|
#include "nsIFormControl.h"
|
|
#include "nsIFrameFrame.h"
|
|
#include "nsIFrameLoader.h"
|
|
#include "nsIFrameTraversal.h"
|
|
#include "nsIGenericFactory.h"
|
|
#include "nsIHTMLDocument.h"
|
|
#include "nsIImageFrame.h"
|
|
#include "nsIImageMap.h"
|
|
#include "nsIInterfaceRequestor.h"
|
|
#include "nsIInterfaceRequestorUtils.h"
|
|
#include "nsILineIterator.h"
|
|
#include "nsILocalFile.h"
|
|
#include "nsINameSpaceManager.h"
|
|
#include "nsIObserver.h"
|
|
#include "nsIPrefBranchInternal.h"
|
|
#include "nsIPrefService.h"
|
|
#include "nsIProperties.h"
|
|
#include "nsIScriptContext.h"
|
|
#include "nsIScriptGlobalObject.h"
|
|
#include "nsIServiceManager.h"
|
|
#include "nsISound.h"
|
|
#include "nsIView.h"
|
|
#include "nsIViewManager.h"
|
|
#include "nsIWebBrowser.h"
|
|
#include "nsIWebBrowserChrome.h"
|
|
#include "nsIWindowWatcher.h"
|
|
#include "nsLayoutCID.h"
|
|
#include "nsPIDOMWindow.h"
|
|
#include "nsStyleContext.h"
|
|
|
|
class nsSpatialNavigationService;
|
|
class nsSpatialNavigation;
|
|
|
|
class nsSpatialNavigation : public nsISpatialNavigation, public nsIDOMKeyListener
|
|
{
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSISPATIALNAVIGATION
|
|
|
|
NS_DECL_NSIDOMEVENTLISTENER
|
|
|
|
// ----- nsIDOMKeyListener ----------------------------
|
|
NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent);
|
|
NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent);
|
|
NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent);
|
|
|
|
nsSpatialNavigation(nsSpatialNavigationService* aService);
|
|
|
|
private:
|
|
~nsSpatialNavigation();
|
|
|
|
nsPresContext* getPresContext(nsIContent* aContent);
|
|
|
|
PRInt64 spatialDistance(int direction, nsRect& a, nsRect& b);
|
|
|
|
nsIDOMWindow* getContentWindow();
|
|
|
|
void setFocusedContent(nsIContent* aContent);
|
|
void getFocusedContent(int direction, nsIContent** aContent);
|
|
|
|
nsresult handleMove(int direction);
|
|
nsresult getContentInDirection(int direction, nsPresContext* presContext, nsRect& focusedRect, nsIFrame* focusedFrame, PRBool aFocusDocuments, PRBool isAREA, nsIContent** aContent);
|
|
|
|
nsCOMPtr<nsIDOMWindow> mTopWindow;
|
|
|
|
nsSpatialNavigationService* mService;
|
|
|
|
PRBool mNavigationFramesState;
|
|
};
|
|
|
|
|
|
|
|
class nsSpatialNavigationService: public nsIObserver
|
|
{
|
|
public:
|
|
nsSpatialNavigationService();
|
|
virtual ~nsSpatialNavigationService();
|
|
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSIOBSERVER
|
|
|
|
nsCOMArray<nsISpatialNavigation> mObjects;
|
|
|
|
PRBool mEnabled;
|
|
PRBool mIgnoreTextFields;
|
|
PRBool mDisableJSWhenFocusing;
|
|
|
|
PRInt32 mKeyCodeLeft;
|
|
PRInt32 mKeyCodeRight;
|
|
PRInt32 mKeyCodeUp;
|
|
PRInt32 mKeyCodeDown;
|
|
PRInt32 mKeyCodeModifier;
|
|
|
|
};
|
|
|
|
extern PRInt32 gRectFudge;
|
|
extern PRInt32 gDirectionalBias;
|
|
|
|
enum {
|
|
eNavLeft = 0,
|
|
eNavUp,
|
|
eNavRight,
|
|
eNavDown
|
|
};
|
|
|
|
|
|
// Utils
|
|
|
|
nscoord* lo_parse_coord_list (char *str, PRInt32* value_cnt);
|
|
nsresult createFrameTraversal (nsPresContext* aPresContext,
|
|
PRInt32 aType,
|
|
PRBool aVisual,
|
|
PRBool aLockInScrollView,
|
|
PRBool aFollowOOFs,
|
|
nsIBidirectionalEnumerator** outTraversal);
|
|
nsresult getEventTargetFromWindow (nsIDOMWindow* aWindow, nsIDOM3EventTarget** aEventTarget, nsIDOMEventGroup** aSystemGroup);
|
|
void getContentFromFrame (nsIContent* c, nsIContent** outContent);
|
|
nsresult getFrameForContent (nsIContent* aContent, nsIFrame** aFrame);
|
|
PRBool isContentOfType (nsIContent* content, const char* type);
|
|
PRBool isArea (nsIContent* content);
|
|
PRBool isMap (nsIFrame* frame);
|
|
PRBool isTargetable (PRBool focusDocuments, nsIFrame* frame);
|
|
nsRect makeRectRelativeToGlobalView (nsIFrame *aFrame);
|
|
void poly2Rect (int sides, nscoord* coord, nsRect* rect);
|
|
void getRectOfAreaElement (nsIFrame* f, nsIDOMHTMLAreaElement* e, nsRect* r);
|
|
PRBool isRectInDirection (int direction, nsRect& focusedRect, nsRect& frameRect);
|
|
PRInt64 spatialDistance (int direction, nsRect& a, nsRect& b);
|
|
void GetWindowFromDocument (nsIDOMDocument* aDocument, nsIDOMWindowInternal** aWindow);
|
|
PRBool IsPartiallyVisible (nsIPresShell* shell, nsIFrame* frame);
|
|
void ScrollWindow (int direction, nsIDOMWindow* window);
|
|
|
|
|
|
|
|
class DisableJSScope
|
|
{
|
|
public:
|
|
DisableJSScope(nsIDOMWindow* window) :
|
|
isEnabled(PR_FALSE), scriptContext(nsnull)
|
|
{
|
|
// My passing null, we don't do a thing
|
|
if (!window)
|
|
return;
|
|
|
|
// so, we want to set the focus to the next element, but
|
|
// we do not want onFocus to fire. The reason for this is
|
|
// that we want to have the "enter" key be able to trigger
|
|
// the targeted link after we have focused it. However,
|
|
// we have found a popular portal has a toolbar that, on
|
|
// onFocus, decides to move the focus as if the targeted
|
|
// content was clicked. The only way that I know how to
|
|
// do this is to disable javascript during this call.
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> sgo (do_QueryInterface(window));
|
|
if (!sgo)
|
|
return;
|
|
|
|
scriptContext = sgo->GetContext();
|
|
if (!scriptContext)
|
|
return;
|
|
|
|
isEnabled = scriptContext->GetScriptsEnabled();
|
|
|
|
if (isEnabled)
|
|
scriptContext->SetScriptsEnabled(PR_FALSE, PR_TRUE);
|
|
}
|
|
|
|
~DisableJSScope()
|
|
{
|
|
if (isEnabled && scriptContext)
|
|
{
|
|
// enable javascript again..
|
|
scriptContext->SetScriptsEnabled(PR_TRUE, PR_TRUE);
|
|
}
|
|
|
|
}
|
|
PRBool isEnabled;
|
|
nsIScriptContext *scriptContext;
|
|
};
|
|
|
|
|