/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * ***** 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 mozilla.org Code. * * The Initial Developer of the Original Code is * Aaron Leventhal. * Portions created by the Initial Developer are Copyright (C) 2001 * 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 "nsCOMPtr.h" #include "nsMemory.h" #include "nsIServiceManager.h" #include "nsIObserverService.h" #include "nsIGenericFactory.h" #include "nsIWebProgress.h" #include "nsIDocumentLoader.h" #include "nsCURILoader.h" #include "nsIDocShell.h" #include "nsIDOMWindow.h" #include "nsIDOMWindowInternal.h" #include "nsIDOMEventTarget.h" #include "nsIDOMNSEvent.h" #include "nsIPrefBranch.h" #include "nsIPrefService.h" #include "nsIRegistry.h" #include "nsString.h" #include "nsIDOMNode.h" #include "nsIPresShell.h" #include "nsIDOMDocument.h" #include "nsIDocument.h" #include "nsISelection.h" #include "nsISelectionController.h" #include "nsICaret.h" // Header for this class #include "nsAccessProxy.h" // #define NS_DEBUG_ACCESS_BUILTIN 1 //////////////////////////////////////////////////////////////////////// NS_IMPL_ISUPPORTS4(nsAccessProxy, nsIObserver, nsISupportsWeakReference, nsIWebProgressListener, nsIDOMEventListener) nsAccessProxy* nsAccessProxy::mInstance = nsnull; nsAccessProxy::nsAccessProxy() { } nsAccessProxy::~nsAccessProxy() { } nsAccessProxy *nsAccessProxy::GetInstance() { if (mInstance == nsnull) { mInstance = new nsAccessProxy(); // Will be released in the module destructor NS_IF_ADDREF(mInstance); } NS_IF_ADDREF(mInstance); return mInstance; } void nsAccessProxy::ReleaseInstance() { NS_IF_RELEASE(nsAccessProxy::mInstance); } NS_IMETHODIMP nsAccessProxy::HandleEvent(nsIDOMEvent* aEvent) { nsresult rv; //////// Get Type of Event into a string called eventName /////// nsAutoString eventNameStr; rv=aEvent->GetType(eventNameStr); if (NS_FAILED(rv)) return rv; // Print event name and styles debugging messages #ifdef NS_DEBUG_ACCESS_BUILTIN printf("\n==== %s event occurred ====\n",NS_ConvertUCS2toUTF8(eventNameStr).get()); #endif ////////// Get Target Node - place in document where event was fired //////////// nsCOMPtr targetNode; nsCOMPtr nsevent(do_QueryInterface(aEvent)); if (nsevent) { rv = nsevent->GetOriginalTarget(getter_AddRefs(targetNode)); if (NS_FAILED(rv)) return rv; } if (!targetNode) return NS_ERROR_NULL_POINTER; nsCOMPtr domNode = do_QueryInterface(targetNode); if (!domNode) return NS_OK; // get the Document and PresShell nsCOMPtr domDoc; nsIPresShell *presShell = nsnull; nsCOMPtr doc; domNode->GetOwnerDocument(getter_AddRefs(domDoc)); if (domDoc) { doc = do_QueryInterface(domDoc); if (doc && doc->GetNumberOfShells()>0) { presShell = doc->GetShellAt(0); } } //return NS_OK; /* if (presShell && eventNameStr.EqualsLiteral("click")) { nsCOMPtr domSelection; presShell->FrameSelection()->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSelection)); if (!domSelection) return NS_OK; nsCOMPtr focusDomNode; domSelection->GetAnchorNode(getter_AddRefs(focusDomNode)); if (focusDomNode) domNode=focusDomNode; // first, tell the caret which selection to use nsCOMPtr caret; presShell->GetCaret(getter_AddRefs(caret)); if (!caret) return NS_OK; caret->SetCaretDOMSelection(domSelection); // tell the pres shell to enable the caret, rather than settings its visibility directly. // this way the presShell's idea of caret visibility is maintained. nsCOMPtr selCon = do_QueryInterface(presShell); if (!selCon) return NS_ERROR_NO_INTERFACE; selCon->SetCaretEnabled(PR_TRUE); caret->SetCaretVisible(PR_TRUE); } */ return NS_OK; } // This method gets called on application startup NS_IMETHODIMP nsAccessProxy::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) { static PRBool accessProxyInstalled; nsresult rv = NS_OK; nsDependentCString aTopicString(aTopic); if (accessProxyInstalled && aTopicString.EqualsLiteral(NS_XPCOM_SHUTDOWN_OBSERVER_ID)) return Release(); if (!accessProxyInstalled && aTopicString.EqualsLiteral(APPSTARTUP_CATEGORY)) { accessProxyInstalled = PR_TRUE; // Set to TRUE even for failure cases - we don't want to try more than once nsCOMPtr progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID)); rv = NS_ERROR_FAILURE; if (progress) { rv = progress->AddProgressListener(NS_STATIC_CAST(nsIWebProgressListener*,this), nsIWebProgress::NOTIFY_STATE_DOCUMENT); if (NS_SUCCEEDED(rv)) AddRef(); } // install xpcom shutdown observer if (NS_SUCCEEDED(rv)) { nsCOMPtr observerService(do_GetService("@mozilla.org/observer-service;1", &rv)); if (NS_SUCCEEDED(rv)) rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE); } } return rv; } NS_IMETHODIMP nsAccessProxy::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus) { /* PRUint32 aStateFlags ... * * ===== What has happened ===== * STATE_START, STATE_REDIRECTING, STATE_TRANSFERRING, * STATE_NEGOTIATING, STATE_STOP * ===== Where did it occur? ===== * STATE_IS_REQUEST, STATE_IS_DOCUMENT, STATE_IS_NETWORK, STATE_IS_WINDOW * ===== Security info ===== * STATE_IS_INSECURE, STATE_IS_BROKEN, STATE_IS_SECURE, STATE_SECURE_HIGH * STATE_SECURE_MED, STATE_SECURE_LOW * */ if ((aStateFlags & (STATE_STOP|STATE_START)) && (aStateFlags & STATE_IS_DOCUMENT)) { // Test for built in text to speech or braille display usage preference // If so, attach event handlers to window. If not, don't. nsCOMPtr prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID)); nsXPIDLCString textToSpeechEngine, brailleDisplayEngine; if (prefBranch) { prefBranch->GetCharPref("accessibility.usetexttospeech", getter_Copies(textToSpeechEngine)); prefBranch->GetCharPref("accessibility.usebrailledisplay", getter_Copies(brailleDisplayEngine)); } if ((textToSpeechEngine && *textToSpeechEngine) || (brailleDisplayEngine && *brailleDisplayEngine)) { // Yes, prefs say we will need handlers for this nsCOMPtr domWindow; aWebProgress->GetDOMWindow(getter_AddRefs(domWindow)); if (domWindow) { nsCOMPtr eventTarget = do_QueryInterface(domWindow); nsCOMPtr windowInternal = do_QueryInterface(domWindow); nsCOMPtr opener; if (windowInternal) windowInternal->GetOpener(getter_AddRefs(opener)); if (eventTarget && opener) { eventTarget->AddEventListener(NS_LITERAL_STRING("keyup"), this, PR_FALSE); eventTarget->AddEventListener(NS_LITERAL_STRING("keypress"), this, PR_FALSE); eventTarget->AddEventListener(NS_LITERAL_STRING("focus"), this, PR_FALSE); eventTarget->AddEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE); eventTarget->AddEventListener(NS_LITERAL_STRING("click"), this, PR_FALSE); // for debugging } } } } return NS_OK; } /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ NS_IMETHODIMP nsAccessProxy::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress) { // We can use this to report the percentage done NS_NOTREACHED("notification excluded in AddProgressListener(...)"); return NS_OK; } /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */ NS_IMETHODIMP nsAccessProxy::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location) { // Load has been verified, it will occur, about to commence NS_NOTREACHED("notification excluded in AddProgressListener(...)"); return NS_OK; } /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ NS_IMETHODIMP nsAccessProxy::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage) { // Status bar has changed NS_NOTREACHED("notification excluded in AddProgressListener(...)"); return NS_OK; } /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */ NS_IMETHODIMP nsAccessProxy::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state) { // Security setting has changed NS_NOTREACHED("notification excluded in AddProgressListener(...)"); return NS_OK; }