Back to index

lightning-sunbird  0.9+nobinonly
nsSpatialNavigationPrivate.h
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Spatial Navigation
00015  *
00016  * The Initial Developer of the Original Code is 
00017  * Douglas F. Turner II  <dougt@meer.net>
00018  * Portions created by the Initial Developer are Copyright (C) 2004-2005
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #include "memory.h"
00038 #include "stdlib.h"
00039 
00040 #include "nspr.h"
00041 
00042 #include "nsXPCOM.h"
00043 #include "nsCOMPtr.h"
00044 #include "nsMemory.h"
00045 #include "nsString.h"
00046 
00047 #include "nsISpatialNavigation.h"
00048 
00049 #include "nsArray.h"
00050 #include "nsDirectoryServiceDefs.h"
00051 #include "nsDirectoryServiceUtils.h"
00052 #include "nsFrameTraversal.h"
00053 #include "nsHTMLAtoms.h"
00054 #include "nsIArray.h"
00055 #include "nsIBaseWindow.h"
00056 #include "nsICategoryManager.h"
00057 #include "nsIChromeEventHandler.h"
00058 #include "nsIComponentManager.h"
00059 #include "nsIDOM3EventTarget.h"
00060 #include "nsIDOMAbstractView.h"
00061 #include "nsIDOMCSSStyleDeclaration.h"
00062 #include "nsIDOMDocument.h"
00063 #include "nsIDOMDocument.h"
00064 #include "nsIDOMDocumentView.h"
00065 #include "nsIDOMElementCSSInlineStyle.h"
00066 #include "nsIDOMEvent.h"
00067 #include "nsIDOMEventGroup.h"
00068 #include "nsIDOMEventReceiver.h"
00069 #include "nsIDOMHTMLAnchorElement.h"
00070 #include "nsIDOMHTMLAreaElement.h"
00071 #include "nsIDOMHTMLCollection.h"
00072 #include "nsIDOMHTMLDocument.h"
00073 #include "nsIDOMHTMLFrameElement.h"
00074 #include "nsIDOMHTMLHtmlElement.h"
00075 #include "nsIDOMHTMLIFrameElement.h"
00076 #include "nsIDOMHTMLInputElement.h"
00077 #include "nsIDOMHTMLTextAreaElement.h"
00078 #include "nsIDOMHTMLMapElement.h"
00079 #include "nsIDOMHTMLOptionElement.h"
00080 #include "nsIDOMHTMLSelectElement.h"
00081 #include "nsIDOMKeyEvent.h"
00082 #include "nsIDOMKeyListener.h"
00083 #include "nsIDOMNSEvent.h"
00084 #include "nsIDOMNSHTMLElement.h"
00085 #include "nsIDOMNSUIEvent.h"
00086 #include "nsIDOMNSHTMLInputElement.h"
00087 #include "nsIDOMNSHTMLTextAreaElement.h"
00088 #include "nsIDOMNode.h"
00089 #include "nsIDOMWindow.h"
00090 #include "nsIDOMWindowInternal.h"
00091 #include "nsIDocShell.h"
00092 #include "nsIDocShellTreeItem.h"
00093 #include "nsIDocShellTreeOwner.h"
00094 #include "nsIDocument.h"
00095 #include "nsIDocumentViewer.h"
00096 #include "nsIEventStateManager.h"
00097 #include "nsIFile.h"
00098 #include "nsIFocusController.h"
00099 #include "nsIFormControl.h"
00100 #include "nsIFrameFrame.h"
00101 #include "nsIFrameLoader.h"
00102 #include "nsIFrameTraversal.h"
00103 #include "nsIGenericFactory.h"
00104 #include "nsIHTMLDocument.h"
00105 #include "nsIImageFrame.h"
00106 #include "nsIImageMap.h"
00107 #include "nsIInterfaceRequestor.h"
00108 #include "nsIInterfaceRequestorUtils.h"
00109 #include "nsILineIterator.h"
00110 #include "nsILocalFile.h"
00111 #include "nsINameSpaceManager.h"
00112 #include "nsINodeInfo.h"
00113 #include "nsIObserver.h"
00114 #include "nsIPrefBranchInternal.h"
00115 #include "nsIPrefService.h"
00116 #include "nsIProperties.h"
00117 #include "nsIScriptContext.h"
00118 #include "nsIScriptGlobalObject.h"
00119 #include "nsIServiceManager.h"
00120 #include "nsISound.h"
00121 #include "nsIView.h"
00122 #include "nsIViewManager.h"
00123 #include "nsIWebBrowser.h"
00124 #include "nsIWebBrowserChrome.h"
00125 #include "nsIWindowWatcher.h"
00126 #include "nsLayoutAtoms.h"
00127 #include "nsLayoutCID.h"
00128 #include "nsPIDOMWindow.h"
00129 #include "nsStyleContext.h"
00130 
00131 class nsSpatialNavigationService;
00132 class nsSpatialNavigation;
00133 
00134 class nsSpatialNavigation : public nsISpatialNavigation, public nsIDOMKeyListener
00135 {
00136 public:
00137   
00138   NS_DECL_ISUPPORTS
00139   NS_DECL_NSISPATIALNAVIGATION
00140   
00141   NS_DECL_NSIDOMEVENTLISTENER
00142   
00143   // ----- nsIDOMKeyListener ----------------------------
00144   NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent);
00145   NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent);
00146   NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent);
00147   
00148   nsSpatialNavigation(nsSpatialNavigationService* aService);
00149   
00150 private:
00151   ~nsSpatialNavigation();
00152   
00153   nsPresContext* getPresContext(nsIContent* aContent);
00154   
00155   PRInt64 spatialDistance(int direction, nsRect& a, nsRect& b);
00156   
00157   nsIDOMWindow* getContentWindow();
00158   
00159   void setFocusedContent(nsIContent* aContent);
00160   void getFocusedContent(int direction, nsIContent** aContent);
00161   
00162   nsresult handleMove(int direction);
00163   nsresult getContentInDirection(int direction, nsPresContext* presContext, nsRect& focusedRect, nsIFrame* focusedFrame, PRBool aFocusDocuments, PRBool isAREA, nsIContent** aContent);
00164 
00165   nsCOMPtr<nsIDOMWindow> mTopWindow;
00166 
00167   nsSpatialNavigationService* mService;
00168 
00169   PRBool mNavigationFramesState;
00170 };
00171 
00172 
00173 
00174 class nsSpatialNavigationService: public nsIObserver 
00175 {
00176 public:  
00177   nsSpatialNavigationService();  
00178   virtual ~nsSpatialNavigationService();  
00179   
00180   NS_DECL_ISUPPORTS
00181   NS_DECL_NSIOBSERVER
00182 
00183   nsCOMArray<nsISpatialNavigation> mObjects;
00184 
00185   PRBool  mEnabled;
00186   PRBool  mIgnoreTextFields;
00187   PRBool  mDisableJSWhenFocusing;
00188 
00189   PRInt32 mKeyCodeLeft;
00190   PRInt32 mKeyCodeRight;
00191   PRInt32 mKeyCodeUp;
00192   PRInt32 mKeyCodeDown;
00193   PRInt32 mKeyCodeModifier;
00194 
00195 };
00196 
00197 extern PRInt32 gRectFudge;
00198 extern PRInt32 gDirectionalBias;
00199 
00200 enum {
00201   eNavLeft = 0,
00202   eNavUp,
00203   eNavRight,
00204   eNavDown
00205 };
00206 
00207 
00208 // Utils
00209 
00210 nscoord* lo_parse_coord_list          (char *str, PRInt32* value_cnt);
00211 nsresult createFrameTraversal         (PRUint32 type, nsPresContext* presContext, nsIBidirectionalEnumerator** outTraversal);
00212 nsresult getEventTargetFromWindow     (nsIDOMWindow* aWindow, nsIDOM3EventTarget** aEventTarget, nsIDOMEventGroup** aSystemGroup);
00213 void     getContentFromFrame          (nsIContent* c, nsIContent** outContent);
00214 nsresult getFrameForContent           (nsIContent* aContent, nsIFrame** aFrame);
00215 PRBool   isContentOfType              (nsIContent* content, const char* type);
00216 PRBool   isArea                       (nsIContent* content);
00217 PRBool   isMap                        (nsIFrame* frame);
00218 PRBool   isTargetable                 (PRBool focusDocuments, nsIFrame* frame);
00219 nsRect   makeRectRelativeToGlobalView (nsIFrame *aFrame);
00220 void     poly2Rect                    (int sides, nscoord* coord, nsRect* rect);
00221 void     getRectOfAreaElement         (nsIFrame* f, nsIDOMHTMLAreaElement* e, nsRect* r);
00222 PRBool   isRectInDirection            (int direction, nsRect& focusedRect, nsRect& frameRect);
00223 PRInt64  spatialDistance              (int direction, nsRect& a, nsRect& b);
00224 void     GetWindowFromDocument        (nsIDOMDocument* aDocument, nsIDOMWindowInternal** aWindow);
00225 PRBool   IsPartiallyVisible           (nsIPresShell* shell, nsIFrame* frame);
00226 void     ScrollWindow                 (int direction, nsIDOMWindow* window);
00227 
00228 
00229 
00230 class DisableJSScope
00231 {
00232 public:
00233   DisableJSScope(nsIDOMWindow* window) :
00234     isEnabled(PR_FALSE), scriptContext(nsnull)
00235   {
00236     // My passing null, we don't do a thing
00237     if (!window)
00238       return;
00239 
00240     // so, we want to set the focus to the next element, but
00241     // we do not want onFocus to fire.  The reason for this is
00242     // that we want to have the "enter" key be able to trigger
00243     // the targeted link after we have focused it.  However,
00244     // we have found a popular portal has a toolbar that, on
00245     // onFocus, decides to move the focus as if the targeted
00246     // content was clicked.  The only way that I know how to
00247     // do this is to disable javascript during this call.
00248 
00249     nsCOMPtr<nsIScriptGlobalObject> sgo (do_QueryInterface(window));
00250     if (!sgo)
00251       return;
00252     
00253     scriptContext = sgo->GetContext();
00254     if (!scriptContext)
00255       return;
00256 
00257     isEnabled = scriptContext->GetScriptsEnabled();
00258     
00259     if (isEnabled)
00260       scriptContext->SetScriptsEnabled(PR_FALSE, PR_TRUE);
00261   }
00262 
00263   ~DisableJSScope()
00264   {
00265     if (isEnabled && scriptContext)
00266     {
00267       // enable javascript again..
00268       scriptContext->SetScriptsEnabled(PR_TRUE, PR_TRUE);
00269     }
00270       
00271   }
00272   PRBool isEnabled;
00273   nsIScriptContext *scriptContext;
00274 };
00275 
00276