Back to index

lightning-sunbird  0.9+nobinonly
nsAccessProxy.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org Code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Aaron Leventhal.
00020  * Portions created by the Initial Developer are Copyright (C) 2001
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsCOMPtr.h"
00040 #include "nsMemory.h"
00041 #include "nsIServiceManager.h"
00042 #include "nsIObserverService.h"
00043 #include "nsIGenericFactory.h"
00044 #include "nsIWebProgress.h"
00045 #include "nsIDocumentLoader.h"
00046 #include "nsCURILoader.h"
00047 #include "nsIDocShell.h"
00048 #include "nsIDOMWindow.h"
00049 #include "nsIDOMWindowInternal.h"
00050 #include "nsIDOMEventTarget.h"
00051 #include "nsIDOMNSEvent.h"
00052 #include "nsIPrefBranch.h"
00053 #include "nsIPrefService.h"
00054 
00055 #include "nsIRegistry.h"
00056 #include "nsString.h"
00057 
00058 #include "nsIDOMNode.h"
00059 #include "nsIPresShell.h"
00060 #include "nsIDOMDocument.h"
00061 #include "nsIDocument.h"
00062 #include "nsISelection.h"
00063 #include "nsISelectionController.h"
00064 #include "nsICaret.h"
00065 
00066 // Header for this class
00067 #include "nsAccessProxy.h"
00068 
00069 // #define NS_DEBUG_ACCESS_BUILTIN 1
00070 
00071 
00073 
00074 
00075 NS_IMPL_ISUPPORTS4(nsAccessProxy, nsIObserver, nsISupportsWeakReference, nsIWebProgressListener, nsIDOMEventListener)
00076 
00077 nsAccessProxy* nsAccessProxy::mInstance = nsnull;
00078 
00079 nsAccessProxy::nsAccessProxy()
00080 {
00081 }
00082 
00083 nsAccessProxy::~nsAccessProxy()
00084 {
00085 }
00086 
00087 nsAccessProxy *nsAccessProxy::GetInstance()
00088 {
00089   if (mInstance == nsnull) {
00090     mInstance = new nsAccessProxy();
00091     // Will be released in the module destructor
00092     NS_IF_ADDREF(mInstance);
00093   }
00094 
00095   NS_IF_ADDREF(mInstance);
00096   return mInstance;
00097 }
00098 
00099 void nsAccessProxy::ReleaseInstance()
00100 {
00101   NS_IF_RELEASE(nsAccessProxy::mInstance);
00102 }
00103 
00104 
00105 NS_IMETHODIMP nsAccessProxy::HandleEvent(nsIDOMEvent* aEvent)
00106 {
00107   nsresult rv;
00108 
00110   nsAutoString eventNameStr;
00111   rv=aEvent->GetType(eventNameStr);
00112   if (NS_FAILED(rv))
00113     return rv;
00114   // Print event name and styles debugging messages
00115   #ifdef NS_DEBUG_ACCESS_BUILTIN
00116   printf("\n==== %s event occurred ====\n",NS_ConvertUCS2toUTF8(eventNameStr).get());
00117   #endif
00118 
00120   nsCOMPtr<nsIDOMEventTarget> targetNode;
00121 
00122   nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
00123 
00124   if (nsevent) {
00125     rv = nsevent->GetOriginalTarget(getter_AddRefs(targetNode));
00126 
00127     if (NS_FAILED(rv))
00128       return rv;
00129   }
00130 
00131   if (!targetNode)
00132     return NS_ERROR_NULL_POINTER;
00133   nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(targetNode);
00134   if (!domNode)
00135     return NS_OK;
00136 
00137   // get the Document and PresShell
00138   nsCOMPtr<nsIDOMDocument> domDoc;
00139   nsIPresShell *presShell = nsnull;
00140   nsCOMPtr<nsIDocument> doc;
00141   domNode->GetOwnerDocument(getter_AddRefs(domDoc));
00142   if (domDoc) {
00143     doc = do_QueryInterface(domDoc);
00144     if (doc && doc->GetNumberOfShells()>0) {
00145       presShell = doc->GetShellAt(0);
00146     }
00147   }
00148   //return  NS_OK;
00149   /*
00150   if (presShell && eventNameStr.EqualsLiteral("click")) {
00151     nsCOMPtr<nsISelection> domSelection;
00152     presShell->FrameSelection()->GetSelection(nsISelectionController::SELECTION_NORMAL,
00153                             getter_AddRefs(domSelection));
00154     if (!domSelection)
00155       return NS_OK;
00156     nsCOMPtr<nsIDOMNode> focusDomNode;
00157     domSelection->GetAnchorNode(getter_AddRefs(focusDomNode));
00158     if (focusDomNode) domNode=focusDomNode;
00159     // first, tell the caret which selection to use
00160     nsCOMPtr<nsICaret> caret;
00161     presShell->GetCaret(getter_AddRefs(caret));
00162     if (!caret) return NS_OK;
00163     caret->SetCaretDOMSelection(domSelection);
00164     // tell the pres shell to enable the caret, rather than settings its visibility directly.
00165     // this way the presShell's idea of caret visibility is maintained.
00166     nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(presShell);
00167     if (!selCon) return NS_ERROR_NO_INTERFACE;
00168     selCon->SetCaretEnabled(PR_TRUE);
00169     caret->SetCaretVisible(PR_TRUE);
00170   }
00171   */
00172 
00173   return NS_OK;
00174 }
00175 
00176 
00177 // This method gets called on application startup
00178 NS_IMETHODIMP nsAccessProxy::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) 
00179 {
00180   static PRBool accessProxyInstalled;
00181 
00182   nsresult rv = NS_OK;
00183   nsDependentCString aTopicString(aTopic);
00184 
00185   if (accessProxyInstalled && aTopicString.EqualsLiteral(NS_XPCOM_SHUTDOWN_OBSERVER_ID))
00186     return Release();
00187 
00188   if (!accessProxyInstalled && aTopicString.EqualsLiteral(APPSTARTUP_CATEGORY)) {
00189     accessProxyInstalled = PR_TRUE; // Set to TRUE even for failure cases - we don't want to try more than once
00190     nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
00191     rv = NS_ERROR_FAILURE;
00192     if (progress) {
00193       rv = progress->AddProgressListener(NS_STATIC_CAST(nsIWebProgressListener*,this),
00194                                          nsIWebProgress::NOTIFY_STATE_DOCUMENT);
00195       if (NS_SUCCEEDED(rv))
00196         AddRef();
00197     }
00198      // install xpcom shutdown observer
00199     if (NS_SUCCEEDED(rv)) {
00200       nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1", &rv));
00201       if (NS_SUCCEEDED(rv)) 
00202         rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
00203     }
00204   }
00205   return rv;
00206 }
00207 
00208 
00209 NS_IMETHODIMP nsAccessProxy::OnStateChange(nsIWebProgress *aWebProgress,
00210   nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
00211 {
00212 /* PRUint32 aStateFlags ...
00213  *
00214  * ===== What has happened =====   
00215  * STATE_START, STATE_REDIRECTING, STATE_TRANSFERRING,
00216  * STATE_NEGOTIATING, STATE_STOP
00217 
00218  * ===== Where did it occur? =====
00219  * STATE_IS_REQUEST, STATE_IS_DOCUMENT, STATE_IS_NETWORK, STATE_IS_WINDOW
00220 
00221  * ===== Security info =====
00222  * STATE_IS_INSECURE, STATE_IS_BROKEN, STATE_IS_SECURE, STATE_SECURE_HIGH
00223  * STATE_SECURE_MED, STATE_SECURE_LOW
00224  *
00225  */
00226 
00227   if ((aStateFlags & (STATE_STOP|STATE_START)) && (aStateFlags & STATE_IS_DOCUMENT)) {
00228     // Test for built in text to speech or braille display usage preference
00229     // If so, attach event handlers to window. If not, don't.
00230     nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
00231     nsXPIDLCString textToSpeechEngine, brailleDisplayEngine;
00232     if (prefBranch) {
00233       prefBranch->GetCharPref("accessibility.usetexttospeech", getter_Copies(textToSpeechEngine));
00234       prefBranch->GetCharPref("accessibility.usebrailledisplay", getter_Copies(brailleDisplayEngine));
00235     }
00236 
00237     if ((textToSpeechEngine && *textToSpeechEngine) || (brailleDisplayEngine && *brailleDisplayEngine)) {  
00238       // Yes, prefs say we will need handlers for this 
00239       nsCOMPtr<nsIDOMWindow> domWindow;
00240       aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
00241 
00242       if (domWindow) {
00243         nsCOMPtr<nsIDOMEventTarget> eventTarget = do_QueryInterface(domWindow);
00244         nsCOMPtr<nsIDOMWindowInternal> windowInternal = do_QueryInterface(domWindow);
00245         nsCOMPtr<nsIDOMWindowInternal> opener;
00246         if (windowInternal)
00247           windowInternal->GetOpener(getter_AddRefs(opener));
00248         if (eventTarget && opener) {
00249           eventTarget->AddEventListener(NS_LITERAL_STRING("keyup"), this, PR_FALSE);
00250           eventTarget->AddEventListener(NS_LITERAL_STRING("keypress"), this, PR_FALSE);
00251           eventTarget->AddEventListener(NS_LITERAL_STRING("focus"), this, PR_FALSE);
00252           eventTarget->AddEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
00253           eventTarget->AddEventListener(NS_LITERAL_STRING("click"), this, PR_FALSE); // for debugging
00254         }
00255       }
00256     }
00257   }
00258 
00259   return NS_OK;
00260 }
00261 
00262 /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
00263 NS_IMETHODIMP nsAccessProxy::OnProgressChange(nsIWebProgress *aWebProgress,
00264   nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress,
00265   PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
00266 {
00267   // We can use this to report the percentage done
00268   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
00269   return NS_OK;
00270 }
00271 
00272 /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
00273 NS_IMETHODIMP nsAccessProxy::OnLocationChange(nsIWebProgress *aWebProgress,
00274   nsIRequest *aRequest, nsIURI *location)
00275 {
00276   // Load has been verified, it will occur, about to commence
00277   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
00278   return NS_OK;
00279 }
00280 
00281 /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
00282 NS_IMETHODIMP nsAccessProxy::OnStatusChange(nsIWebProgress *aWebProgress,
00283   nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
00284 {
00285   // Status bar has changed
00286   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
00287   return NS_OK;
00288 }
00289 
00290 /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
00291 NS_IMETHODIMP nsAccessProxy::OnSecurityChange(nsIWebProgress *aWebProgress,
00292   nsIRequest *aRequest, PRUint32 state)
00293 {
00294   // Security setting has changed
00295   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
00296   return NS_OK;
00297 }
00298