mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
298 lines
10 KiB
C++
298 lines
10 KiB
C++
/* -*- 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 "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_ConvertUTF16toUTF8(eventNameStr).get());
|
|
#endif
|
|
|
|
////////// Get Target Node - place in document where event was fired ////////////
|
|
nsCOMPtr<nsIDOMEventTarget> targetNode;
|
|
|
|
nsCOMPtr<nsIDOMNSEvent> 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<nsIDOMNode> domNode = do_QueryInterface(targetNode);
|
|
if (!domNode)
|
|
return NS_OK;
|
|
|
|
// get the Document and PresShell
|
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
nsIPresShell *presShell = nsnull;
|
|
nsCOMPtr<nsIDocument> doc;
|
|
domNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
|
if (domDoc) {
|
|
doc = do_QueryInterface(domDoc);
|
|
if (doc) {
|
|
presShell = doc->GetPrimaryShell();
|
|
}
|
|
}
|
|
//return NS_OK;
|
|
/*
|
|
if (presShell && eventNameStr.EqualsLiteral("click")) {
|
|
nsCOMPtr<nsISelection> domSelection;
|
|
presShell->FrameSelection()->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
|
getter_AddRefs(domSelection));
|
|
if (!domSelection)
|
|
return NS_OK;
|
|
nsCOMPtr<nsIDOMNode> focusDomNode;
|
|
domSelection->GetAnchorNode(getter_AddRefs(focusDomNode));
|
|
if (focusDomNode) domNode=focusDomNode;
|
|
// first, tell the caret which selection to use
|
|
nsCOMPtr<nsICaret> 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<nsISelectionController> 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<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
|
|
rv = NS_ERROR_FAILURE;
|
|
if (progress) {
|
|
rv = progress->AddProgressListener(static_cast<nsIWebProgressListener*>(this),
|
|
nsIWebProgress::NOTIFY_STATE_DOCUMENT);
|
|
if (NS_SUCCEEDED(rv))
|
|
AddRef();
|
|
}
|
|
// install xpcom shutdown observer
|
|
if (NS_SUCCEEDED(rv)) {
|
|
nsCOMPtr<nsIObserverService> 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<nsIPrefBranch> 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<nsIDOMWindow> domWindow;
|
|
aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
|
|
|
|
if (domWindow) {
|
|
nsCOMPtr<nsIDOMEventTarget> eventTarget = do_QueryInterface(domWindow);
|
|
nsCOMPtr<nsIDOMWindowInternal> windowInternal = do_QueryInterface(domWindow);
|
|
nsCOMPtr<nsIDOMWindowInternal> 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;
|
|
}
|
|
|