Fix for 54203. r=saari, a=brendan

This commit is contained in:
hyatt%netscape.com 2000-11-04 08:21:20 +00:00
Родитель a62bed2bb1
Коммит e0c292d77e
37 изменённых файлов: 1540 добавлений и 2667 удалений

Просмотреть файл

@ -62,9 +62,11 @@
#include "nsIServiceManager.h"
#include "nsIPref.h"
#include "nsIChromeEventHandler.h"
#include "nsIFocusController.h"
#include "nsXULAtoms.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIObserverService.h"
#include "nsIDocShell.h"
#include "nsIMarkupDocumentViewer.h"
@ -333,16 +335,16 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
blurevent.message = NS_BLUR_CONTENT;
if(gLastFocusedPresContext) {
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
if(ourWindow) {
ourWindow->GetRootCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher)
commandDispatcher->SetSuppressFocus(PR_TRUE);
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController)
focusController->SetSuppressFocus(PR_TRUE);
}
gLastFocusedDocument->HandleDOMEvent(gLastFocusedPresContext, &blurevent, nsnull, NS_EVENT_FLAG_INIT, &blurstatus);
@ -350,8 +352,8 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
gLastFocusedContent->HandleDOMEvent(gLastFocusedPresContext, &blurevent, nsnull, NS_EVENT_FLAG_INIT, &blurstatus);
if (commandDispatcher) {
commandDispatcher->SetSuppressFocus(PR_FALSE);
if (focusController) {
focusController->SetSuppressFocus(PR_FALSE);
}
}
}
@ -399,56 +401,30 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
// objects.
EnsureDocument(aPresContext);
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIDOMElement> focusedElement;
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(mDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
// Obtain focus info from the command dispatcher.
commandDispatcher->GetFocusedWindow(getter_AddRefs(focusedWindow));
commandDispatcher->GetFocusedElement(getter_AddRefs(focusedElement));
commandDispatcher->SetSuppressFocusScroll(PR_TRUE);
}
nsCOMPtr<nsIScriptGlobalObject> globalObj;
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObj));
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(globalObj));
win->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
// Obtain focus info from the command dispatcher.
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
focusController->GetFocusedElement(getter_AddRefs(focusedElement));
focusController->SetSuppressFocusScroll(PR_TRUE);
}
if (!focusedWindow) {
nsCOMPtr<nsIScriptGlobalObject> globalObject;
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
focusedWindow = do_QueryInterface(globalObject);
nsCOMPtr<nsIScriptGlobalObject> globalObject;
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
focusedWindow = do_QueryInterface(globalObject);
}
// Sill no focused XULDocument, that is bad
if(!xulDoc && focusedWindow)
{
nsCOMPtr<nsPIDOMWindow> privateWindow = do_QueryInterface(focusedWindow);
if(privateWindow){
nsCOMPtr<nsIDOMWindowInternal> privateRootWindow;
privateWindow->GetPrivateRoot(getter_AddRefs(privateRootWindow));
if(privateRootWindow) {
nsCOMPtr<nsIDOMDocument> privateParentDoc;
privateRootWindow->GetDocument(getter_AddRefs(privateParentDoc));
xulDoc = do_QueryInterface(privateParentDoc);
}
}
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
// Obtain focus info from the command dispatcher.
commandDispatcher->GetFocusedWindow(getter_AddRefs(focusedWindow));
commandDispatcher->GetFocusedElement(getter_AddRefs(focusedElement));
commandDispatcher->SetSuppressFocusScroll(PR_TRUE);
}
}
}
// Focus the DOM window.
NS_WARN_IF_FALSE(focusedWindow,"check why focusedWindow is null!!!");
if(focusedWindow) {
@ -470,16 +446,16 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
}
}
if (commandDispatcher) {
commandDispatcher->SetActive(PR_TRUE);
if (focusController) {
focusController->SetActive(PR_TRUE);
PRBool isSuppressed;
commandDispatcher->GetSuppressFocus(&isSuppressed);
focusController->GetSuppressFocus(&isSuppressed);
while(isSuppressed){
commandDispatcher->SetSuppressFocus(PR_FALSE); // Unsuppress and let the command dispatcher listen again.
commandDispatcher->GetSuppressFocus(&isSuppressed);
focusController->SetSuppressFocus(PR_FALSE); // Unsuppress and let the command dispatcher listen again.
focusController->GetSuppressFocus(&isSuppressed);
}
commandDispatcher->SetSuppressFocusScroll(PR_FALSE);
focusController->SetSuppressFocusScroll(PR_FALSE);
}
}
break;
@ -508,24 +484,14 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
// de-activation. This will cause it to remember the last
// focused sub-window and sub-element for this top-level
// window.
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
if(ourWindow) {
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
if(rootWindow) {
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
// Suppress the command dispatcher.
commandDispatcher->SetSuppressFocus(PR_TRUE);
}
}
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
// Suppress the command dispatcher.
focusController->SetSuppressFocus(PR_TRUE);
}
}
@ -577,9 +543,9 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
gLastFocusedPresContext = nsnull;
}
if (commandDispatcher) {
commandDispatcher->SetActive(PR_FALSE);
//commandDispatcher->SetSuppressFocus(PR_FALSE);
if (focusController) {
focusController->SetActive(PR_FALSE);
//focusController->SetSuppressFocus(PR_FALSE);
}
}
@ -955,7 +921,6 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
PRInt32 action = 0;
PRInt32 numLines = 0;
PRBool aBool;
if (msEvent->isShift) {
mPrefService->GetIntPref("mousewheel.withshiftkey.action", &action);
mPrefService->GetBoolPref("mousewheel.withshiftkey.sysnumlines",
@ -2687,8 +2652,8 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// Make sure we're not switching command dispatchers, if so, surpress the blurred one
if(gLastFocusedDocument && mDocument) {
nsCOMPtr<nsIDOMXULCommandDispatcher> newCommandDispatcher;
nsCOMPtr<nsIDOMXULCommandDispatcher> oldCommandDispatcher;
nsCOMPtr<nsIFocusController> newFocusController;
nsCOMPtr<nsIFocusController> oldFocusController;
nsCOMPtr<nsPIDOMWindow> oldPIDOMWindow;
nsCOMPtr<nsPIDOMWindow> newPIDOMWindow;
nsCOMPtr<nsIScriptGlobalObject> oldGlobal;
@ -2698,11 +2663,11 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(newGlobal);
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(oldGlobal);
if(newWindow)
newWindow->GetRootCommandDispatcher(getter_AddRefs(newCommandDispatcher));
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
if(oldWindow)
oldWindow->GetRootCommandDispatcher(getter_AddRefs(oldCommandDispatcher));
if(oldCommandDispatcher && oldCommandDispatcher != newCommandDispatcher)
oldCommandDispatcher->SetSuppressFocus(PR_TRUE);
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
if(oldFocusController && oldFocusController != newFocusController)
oldFocusController->SetSuppressFocus(PR_TRUE);
}
nsCOMPtr<nsIEventStateManager> esm;
@ -2737,8 +2702,8 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// Make sure we're not switching command dispatchers, if so, surpress the blurred one
if(mDocument) {
nsCOMPtr<nsIDOMXULCommandDispatcher> newCommandDispatcher;
nsCOMPtr<nsIDOMXULCommandDispatcher> oldCommandDispatcher;
nsCOMPtr<nsIFocusController> newFocusController;
nsCOMPtr<nsIFocusController> oldFocusController;
nsCOMPtr<nsPIDOMWindow> oldPIDOMWindow;
nsCOMPtr<nsPIDOMWindow> newPIDOMWindow;
nsCOMPtr<nsIScriptGlobalObject> oldGlobal;
@ -2748,10 +2713,10 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(newGlobal);
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(oldGlobal);
newWindow->GetRootCommandDispatcher(getter_AddRefs(newCommandDispatcher));
oldWindow->GetRootCommandDispatcher(getter_AddRefs(oldCommandDispatcher));
if(oldCommandDispatcher && oldCommandDispatcher != newCommandDispatcher)
oldCommandDispatcher->SetSuppressFocus(PR_TRUE);
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
if(oldFocusController && oldFocusController != newFocusController)
oldFocusController->SetSuppressFocus(PR_TRUE);
}
nsCOMPtr<nsIEventStateManager> esm;
@ -2963,6 +2928,12 @@ nsEventStateManager::DispatchNewEvent(nsISupports* aTarget, nsIDOMEvent* aEvent)
if (target) {
ret = target->HandleDOMEvent(mPresContext, innerEvent, &aEvent, NS_EVENT_FLAG_INIT, &status);
}
else {
nsCOMPtr<nsIChromeEventHandler> target(do_QueryInterface(aTarget));
if (target) {
ret = target->HandleChromeEvent(mPresContext, innerEvent, &aEvent, NS_EVENT_FLAG_INIT, &status);
}
}
}
}
}

Просмотреть файл

@ -42,12 +42,13 @@
#include "nsIDOMNSHTMLTextAreaElement.h"
#include "nsIDOMNSHTMLInputElement.h"
#include "nsIDOMText.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIFocusController.h"
#include "nsIEventListenerManager.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMEventListener.h"
#include "nsIPrivateDOMEvent.h"
#include "nsPIDOMWindow.h"
#include "nsPIWindowRoot.h"
#include "nsIDOMWindowInternal.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
@ -218,29 +219,36 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven
// Instead of executing JS, let's get the controller for the bound
// element and call doCommand on it.
nsCOMPtr<nsIController> controller;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsPIDOMWindow> privateWindow(do_QueryInterface(aReceiver));
if (!privateWindow) {
nsCOMPtr<nsIContent> elt(do_QueryInterface(aReceiver));
nsCOMPtr<nsIDocument> doc;
if (elt)
elt->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsPIWindowRoot> windowRoot(do_QueryInterface(aReceiver));
if (windowRoot) {
windowRoot->GetFocusController(getter_AddRefs(focusController));
}
else {
nsCOMPtr<nsPIDOMWindow> privateWindow(do_QueryInterface(aReceiver));
if (!privateWindow) {
nsCOMPtr<nsIContent> elt(do_QueryInterface(aReceiver));
nsCOMPtr<nsIDocument> doc;
if (elt)
elt->GetDocument(*getter_AddRefs(doc));
if (!doc)
doc = do_QueryInterface(aReceiver);
if (!doc)
doc = do_QueryInterface(aReceiver);
if (!doc)
return NS_ERROR_FAILURE;
if (!doc)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIScriptGlobalObject> globalObject;
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
privateWindow = do_QueryInterface(globalObject);
nsCOMPtr<nsIScriptGlobalObject> globalObject;
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
privateWindow = do_QueryInterface(globalObject);
}
privateWindow->GetRootFocusController(getter_AddRefs(focusController));
}
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
privateWindow->GetRootCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher)
commandDispatcher->GetControllerForCommand(command, getter_AddRefs(controller));
if (focusController)
focusController->GetControllerForCommand(command, getter_AddRefs(controller));
else GetController(aReceiver, getter_AddRefs(controller)); // We're attached to the receiver possibly.
if (controller)
@ -271,12 +279,25 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven
mHandlerElement->GetAttribute(kNameSpaceID_None, kOnCommandAtom, handlerText);
if (handlerText.IsEmpty())
return NS_ERROR_FAILURE; // For whatever reason, they didn't give us anything to do.
aEvent->PreventDefault(); // Preventing default for XUL key handlers
aEvent->PreventDefault(); // Preventing default for XUL key handlers
}
}
// Compile the handler and bind it to the element.
nsCOMPtr<nsIScriptGlobalObject> boundGlobal(do_QueryInterface(aReceiver));
nsCOMPtr<nsIScriptGlobalObject> boundGlobal;
nsCOMPtr<nsPIWindowRoot> winRoot(do_QueryInterface(aReceiver));
if (winRoot) {
nsCOMPtr<nsIFocusController> focusController;
winRoot->GetFocusController(getter_AddRefs(focusController));
nsCOMPtr<nsIDOMWindowInternal> win;
focusController->GetFocusedWindow(getter_AddRefs(win));
nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(win));
nsCOMPtr<nsIDOMWindowInternal> rootWin;
piWin->GetPrivateRoot(getter_AddRefs(rootWin));
boundGlobal = do_QueryInterface(rootWin);
}
else boundGlobal = do_QueryInterface(aReceiver);
if (!boundGlobal) {
nsCOMPtr<nsIDocument> boundDocument(do_QueryInterface(aReceiver));
if (!boundDocument) {
@ -293,7 +314,8 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven
nsCOMPtr<nsIScriptContext> boundContext;
boundGlobal->GetContext(getter_AddRefs(boundContext));
nsCOMPtr<nsIScriptObjectOwner> owner(do_QueryInterface(aReceiver));
nsCOMPtr<nsIScriptObjectOwner> owner(do_QueryInterface(winRoot ? boundGlobal : aReceiver));
void* scriptObject;
owner->GetScriptObject(boundContext, &scriptObject);

Просмотреть файл

@ -39,12 +39,13 @@
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindowInternal.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIFocusController.h"
#include "nsIDocShell.h"
#include "nsIPresShell.h"
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsIDOMElement.h"
#include "nsPIWindowRoot.h"
PRUint32 nsXBLWindowKeyHandler::gRefCnt = 0;
nsIAtom* nsXBLWindowKeyHandler::kKeyDownAtom = nsnull;
@ -90,16 +91,16 @@ NS_IMPL_ISUPPORTS1(nsXBLWindowKeyHandler, nsIDOMKeyListener)
PRBool
nsXBLWindowKeyHandler::IsEditor()
{
nsCOMPtr<nsPIDOMWindow> privateWindow(do_QueryInterface(mReceiver));
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
privateWindow->GetRootCommandDispatcher(getter_AddRefs(commandDispatcher));
if (!commandDispatcher) {
NS_WARNING("********* Problem for embedding. They have no command dispatcher!!!\n");
nsCOMPtr<nsPIWindowRoot> windowRoot(do_QueryInterface(mReceiver));
nsCOMPtr<nsIFocusController> focusController;
windowRoot->GetFocusController(getter_AddRefs(focusController));
if (!focusController) {
NS_WARNING("********* Something went wrong! No focus controller on the root!!!\n");
return PR_FALSE;
}
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
commandDispatcher->GetFocusedWindow(getter_AddRefs(focusedWindow));
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
if (!focusedWindow)
return PR_FALSE;

Просмотреть файл

@ -29,6 +29,7 @@
*/
#include "nsIContent.h"
#include "nsIFocusController.h"
#include "nsIControllers.h"
#include "nsIDOMDocument.h"
#include "nsIDOMXULDocument.h"
@ -55,19 +56,18 @@ static PRLogModuleInfo* gLog;
////////////////////////////////////////////////////////////////////////
nsXULCommandDispatcher::nsXULCommandDispatcher(void)
: mScriptObject(nsnull), mSuppressFocus(0),
mActive(PR_FALSE), mFocusInitialized(PR_FALSE), mUpdaters(nsnull)
nsXULCommandDispatcher::nsXULCommandDispatcher(nsIDocument* aDocument)
: mScriptObject(nsnull), mDocument(aDocument), mFocusController(nsnull), mUpdaters(nsnull)
{
NS_INIT_REFCNT();
#ifdef PR_LOGGING
if (! gLog)
gLog = PR_NewLogModule("nsXULCommandDispatcher");
if (! gLog)
gLog = PR_NewLogModule("nsXULCommandDispatcher");
#endif
}
nsXULCommandDispatcher::~nsXULCommandDispatcher(void)
nsXULCommandDispatcher::~nsXULCommandDispatcher()
{
while (mUpdaters) {
Updater* doomed = mUpdaters;
@ -82,45 +82,58 @@ NS_IMPL_RELEASE(nsXULCommandDispatcher)
NS_IMETHODIMP
nsXULCommandDispatcher::QueryInterface(REFNSIID iid, void** result)
{
if (! result)
return NS_ERROR_NULL_POINTER;
if (! result)
return NS_ERROR_NULL_POINTER;
*result = nsnull;
if (iid.Equals(NS_GET_IID(nsISupports)) ||
iid.Equals(NS_GET_IID(nsIDOMXULCommandDispatcher))) {
*result = NS_STATIC_CAST(nsIDOMXULCommandDispatcher*, this);
}
else if (iid.Equals(NS_GET_IID(nsIDOMFocusListener)) ||
iid.Equals(NS_GET_IID(nsIDOMEventListener))) {
*result = NS_STATIC_CAST(nsIDOMFocusListener*, this);
}
else if (iid.Equals(NS_GET_IID(nsIScriptObjectOwner))) {
*result = NS_STATIC_CAST(nsIScriptObjectOwner*, this);
}
else if (iid.Equals(NS_GET_IID(nsISupportsWeakReference))) {
*result = NS_STATIC_CAST(nsISupportsWeakReference*, this);
}
else {
return NS_NOINTERFACE;
}
*result = nsnull;
if (iid.Equals(NS_GET_IID(nsISupports)) ||
iid.Equals(NS_GET_IID(nsIDOMXULCommandDispatcher))) {
*result = NS_STATIC_CAST(nsIDOMXULCommandDispatcher*, this);
}
else if (iid.Equals(NS_GET_IID(nsIScriptObjectOwner))) {
*result = NS_STATIC_CAST(nsIScriptObjectOwner*, this);
}
else if (iid.Equals(NS_GET_IID(nsISupportsWeakReference))) {
*result = NS_STATIC_CAST(nsISupportsWeakReference*, this);
}
else {
return NS_NOINTERFACE;
}
NS_ADDREF_THIS();
return NS_OK;
NS_ADDREF_THIS();
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::Create(nsIDOMXULCommandDispatcher** aResult)
nsXULCommandDispatcher::Create(nsIDocument* aDoc, nsIDOMXULCommandDispatcher** aResult)
{
nsXULCommandDispatcher* dispatcher = new nsXULCommandDispatcher();
if (! dispatcher)
return NS_ERROR_OUT_OF_MEMORY;
nsXULCommandDispatcher* dispatcher = new nsXULCommandDispatcher(aDoc);
if (!dispatcher)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = dispatcher;
NS_ADDREF(*aResult);
return NS_OK;
*aResult = dispatcher;
NS_ADDREF(*aResult);
return NS_OK;
}
void
nsXULCommandDispatcher::EnsureFocusController()
{
if (!mFocusController) {
nsCOMPtr<nsIScriptGlobalObject> global;
mDocument->GetScriptGlobalObject(getter_AddRefs(global));
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(global));
// An inelegant way to retrieve this to be sure, but we are
// guaranteed that the focus controller outlives us, so it
// is safe to hold on to it (since we can't die until it has
// died).
nsCOMPtr<nsIFocusController> focus;
win->GetRootFocusController(getter_AddRefs(focus));
mFocusController = focus; // Store as a weak ptr.
}
}
////////////////////////////////////////////////////////////////
// nsIDOMXULTracker Interface
@ -128,35 +141,31 @@ nsXULCommandDispatcher::Create(nsIDOMXULCommandDispatcher** aResult)
NS_IMETHODIMP
nsXULCommandDispatcher::GetFocusedElement(nsIDOMElement** aElement)
{
*aElement = mCurrentElement;
NS_IF_ADDREF(*aElement);
return NS_OK;
EnsureFocusController();
return mFocusController->GetFocusedElement(aElement);
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetFocusedWindow(nsIDOMWindowInternal** aWindow)
{
*aWindow = mCurrentWindow;
NS_IF_ADDREF(*aWindow);
return NS_OK;
EnsureFocusController();
return mFocusController->GetFocusedWindow(aWindow);
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetFocusedElement(nsIDOMElement* aElement)
{
mCurrentElement = aElement;
// Need to update focus commands when focus switches from
// an element to no element, so don't test mCurrentElement
// before updating.
UpdateCommands(NS_LITERAL_STRING("focus"));
return NS_OK;
EnsureFocusController();
return mFocusController->SetFocusedElement(aElement);
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetFocusedWindow(nsIDOMWindowInternal* aWindow)
{
mCurrentWindow = aWindow;
return NS_OK;
EnsureFocusController();
if (mFocusController)
return mFocusController->SetFocusedWindow(aWindow);
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
@ -164,110 +173,114 @@ nsXULCommandDispatcher::AddCommandUpdater(nsIDOMElement* aElement,
const nsAReadableString& aEvents,
const nsAReadableString& aTargets)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
Updater* updater = mUpdaters;
Updater** link = &mUpdaters;
Updater* updater = mUpdaters;
Updater** link = &mUpdaters;
while (updater) {
if (updater->mElement == aElement) {
while (updater) {
if (updater->mElement == aElement) {
#ifdef NS_DEBUG
nsCAutoString eventsC, targetsC, aeventsC, atargetsC;
eventsC.AssignWithConversion(updater->mEvents);
targetsC.AssignWithConversion(updater->mTargets);
aeventsC.Assign(NS_ConvertUCS2toUTF8(aEvents));
atargetsC.Assign(NS_ConvertUCS2toUTF8(aTargets));
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] replace %p(events=%s targets=%s) with (events=%s targets=%s)",
this, aElement,
(const char*) eventsC,
(const char*) targetsC,
(const char*) aeventsC,
(const char*) atargetsC));
nsCAutoString eventsC, targetsC, aeventsC, atargetsC;
eventsC.AssignWithConversion(updater->mEvents);
targetsC.AssignWithConversion(updater->mTargets);
aeventsC.Assign(NS_ConvertUCS2toUTF8(aEvents));
atargetsC.Assign(NS_ConvertUCS2toUTF8(aTargets));
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] replace %p(events=%s targets=%s) with (events=%s targets=%s)",
this, aElement,
(const char*) eventsC,
(const char*) targetsC,
(const char*) aeventsC,
(const char*) atargetsC));
#endif
// If the updater was already in the list, then replace
// (?) the 'events' and 'targets' filters with the new
// specification.
updater->mEvents = aEvents;
updater->mTargets = aTargets;
return NS_OK;
}
link = &(updater->mNext);
updater = updater->mNext;
// If the updater was already in the list, then replace
// (?) the 'events' and 'targets' filters with the new
// specification.
updater->mEvents = aEvents;
updater->mTargets = aTargets;
return NS_OK;
}
#ifdef NS_DEBUG
nsCAutoString aeventsC, atargetsC;
aeventsC.Assign(NS_ConvertUCS2toUTF8(aEvents));
atargetsC.Assign(NS_ConvertUCS2toUTF8(aTargets));
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] add %p(events=%s targets=%s)",
this, aElement,
(const char*) aeventsC,
(const char*) atargetsC));
link = &(updater->mNext);
updater = updater->mNext;
}
#ifdef NS_DEBUG
nsCAutoString aeventsC, atargetsC;
aeventsC.Assign(NS_ConvertUCS2toUTF8(aEvents));
atargetsC.Assign(NS_ConvertUCS2toUTF8(aTargets));
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] add %p(events=%s targets=%s)",
this, aElement,
(const char*) aeventsC,
(const char*) atargetsC));
#endif
// If we get here, this is a new updater. Append it to the list.
updater = new Updater(aElement, aEvents, aTargets);
if (! updater)
return NS_ERROR_OUT_OF_MEMORY;
// If we get here, this is a new updater. Append it to the list.
updater = new Updater(aElement, aEvents, aTargets);
if (! updater)
return NS_ERROR_OUT_OF_MEMORY;
*link = updater;
return NS_OK;
*link = updater;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::RemoveCommandUpdater(nsIDOMElement* aElement)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
Updater* updater = mUpdaters;
Updater** link = &mUpdaters;
Updater* updater = mUpdaters;
Updater** link = &mUpdaters;
while (updater) {
if (updater->mElement == aElement) {
while (updater) {
if (updater->mElement == aElement) {
#ifdef NS_DEBUG
nsCAutoString eventsC, targetsC;
eventsC.AssignWithConversion(updater->mEvents);
targetsC.AssignWithConversion(updater->mTargets);
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] remove %p(events=%s targets=%s)",
this, aElement,
(const char*) eventsC,
(const char*) targetsC));
nsCAutoString eventsC, targetsC;
eventsC.AssignWithConversion(updater->mEvents);
targetsC.AssignWithConversion(updater->mTargets);
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] remove %p(events=%s targets=%s)",
this, aElement,
(const char*) eventsC,
(const char*) targetsC));
#endif
*link = updater->mNext;
delete updater;
return NS_OK;
}
link = &(updater->mNext);
updater = updater->mNext;
*link = updater->mNext;
delete updater;
return NS_OK;
}
// Hmm. Not found. Oh well.
return NS_OK;
link = &(updater->mNext);
updater = updater->mNext;
}
// Hmm. Not found. Oh well.
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::UpdateCommands(const nsAReadableString& aEventName)
{
nsresult rv;
nsresult rv;
nsAutoString id;
if (mCurrentElement) {
rv = mCurrentElement->GetAttribute(NS_ConvertASCIItoUCS2("id"), id);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get element's id");
if (NS_FAILED(rv)) return rv;
}
EnsureFocusController();
nsAutoString id;
nsCOMPtr<nsIDOMElement> element;
mFocusController->GetFocusedElement(getter_AddRefs(element));
if (element) {
rv = element->GetAttribute(NS_ConvertASCIItoUCS2("id"), id);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get element's id");
if (NS_FAILED(rv)) return rv;
}
#if 0
{
@ -277,226 +290,84 @@ nsXULCommandDispatcher::UpdateCommands(const nsAReadableString& aEventName)
}
#endif
for (Updater* updater = mUpdaters; updater != nsnull; updater = updater->mNext) {
// Skip any nodes that don't match our 'events' or 'targets'
// filters.
if (! Matches(updater->mEvents, aEventName))
continue;
for (Updater* updater = mUpdaters; updater != nsnull; updater = updater->mNext) {
// Skip any nodes that don't match our 'events' or 'targets'
// filters.
if (! Matches(updater->mEvents, aEventName))
continue;
if (! Matches(updater->mTargets, id))
continue;
if (! Matches(updater->mTargets, id))
continue;
nsCOMPtr<nsIContent> content = do_QueryInterface(updater->mElement);
NS_ASSERTION(content != nsnull, "not an nsIContent");
if (! content)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIContent> content = do_QueryInterface(updater->mElement);
NS_ASSERTION(content != nsnull, "not an nsIContent");
if (! content)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIDocument> document;
rv = content->GetDocument(*getter_AddRefs(document));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get document");
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDocument> document;
rv = content->GetDocument(*getter_AddRefs(document));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get document");
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(document != nsnull, "element has no document");
if (! document)
continue;
NS_ASSERTION(document != nsnull, "element has no document");
if (! document)
continue;
#ifdef NS_DEBUG
nsCAutoString aeventnameC;
aeventnameC.Assign(NS_ConvertUCS2toUTF8(aEventName));
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] update %p event=%s",
this, updater->mElement,
(const char*) aeventnameC));
nsCAutoString aeventnameC;
aeventnameC.Assign(NS_ConvertUCS2toUTF8(aEventName));
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] update %p event=%s",
this, updater->mElement,
(const char*) aeventnameC));
#endif
PRInt32 count = document->GetNumberOfShells();
for (PRInt32 i = 0; i < count; i++) {
nsCOMPtr<nsIPresShell> shell = dont_AddRef(document->GetShellAt(i));
if (! shell)
continue;
// Retrieve the context in which our DOM event will fire.
nsCOMPtr<nsIPresContext> context;
rv = shell->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(rv)) return rv;
PRInt32 count = document->GetNumberOfShells();
for (PRInt32 i = 0; i < count; i++) {
nsCOMPtr<nsIPresShell> shell = dont_AddRef(document->GetShellAt(i));
if (! shell)
continue;
// Retrieve the context in which our DOM event will fire.
nsCOMPtr<nsIPresContext> context;
rv = shell->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(rv)) return rv;
// Handle the DOM event
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_XUL_COMMAND_UPDATE;
content->HandleDOMEvent(context, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
// Handle the DOM event
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_XUL_COMMAND_UPDATE;
content->HandleDOMEvent(context, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetControllers(nsIControllers** aResult)
{
//XXX: we should fix this so there's a generic interface that describes controllers,
// so this code would have no special knowledge of what object might have controllers.
if (mCurrentElement) {
nsCOMPtr<nsIDOMXULElement> xulElement = do_QueryInterface(mCurrentElement);
if (xulElement)
return xulElement->GetControllers(aResult);
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextArea = do_QueryInterface(mCurrentElement);
if (htmlTextArea)
return htmlTextArea->GetControllers(aResult);
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement = do_QueryInterface(mCurrentElement);
if (htmlInputElement)
return htmlInputElement->GetControllers(aResult);
}
else if (mCurrentWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(mCurrentWindow);
if (domWindow)
return domWindow->GetControllers(aResult);
}
*aResult = nsnull;
return NS_OK;
}
/////
// nsIDOMFocusListener
/////
nsresult
nsXULCommandDispatcher::Focus(nsIDOMEvent* aEvent)
{
if (mSuppressFocus)
return NS_OK;
nsCOMPtr<nsIDOMEventTarget> t;
aEvent->GetOriginalTarget(getter_AddRefs(t));
#if 0
printf("%d : Focus occurred on: ", this);
nsCOMPtr<nsIDOMElement> domDebugElement = do_QueryInterface(t);
if (domDebugElement) {
printf("A Focusable DOM Element");
}
nsCOMPtr<nsIDOMDocument> domDebugDocument = do_QueryInterface(t);
if (domDebugDocument) {
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(t);
if (htmlDoc) {
printf("Window with an HTML doc (happens twice)");
}
else printf("Window with a XUL doc (happens twice)");
}
printf("\n");
#endif /* DEBUG_hyatt */
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(t);
if (domElement && (domElement != mCurrentElement)) {
SetFocusedElement(domElement);
// Also set focus to our innermost window.
// XXX Must be done for the Ender case, since ender causes a blur,
// but we don't hear the subsequent focus to the Ender window.
nsCOMPtr<nsIDOMDocument> ownerDoc;
domElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
nsCOMPtr<nsIDOMWindowInternal> domWindow;
GetParentWindowFromDocument(ownerDoc, getter_AddRefs(domWindow));
if (domWindow)
SetFocusedWindow(domWindow);
}
else {
// We're focusing a window. We only want to do an update commands
// if no element is focused.
nsCOMPtr<nsIDOMWindowInternal> domWindow;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(t);
if (domDoc) {
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
if (domWindow) {
SetFocusedWindow(domWindow);
if (mCurrentElement) {
// Make sure this element is in our window. If not, we
// should clear this field.
nsCOMPtr<nsIDOMDocument> ownerDoc;
mCurrentElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
nsCOMPtr<nsIDOMDocument> windowDoc;
mCurrentWindow->GetDocument(getter_AddRefs(windowDoc));
if (ownerDoc != windowDoc)
mCurrentElement = nsnull;
}
if (!mCurrentElement)
UpdateCommands(NS_LITERAL_STRING("focus"));
}
}
}
return NS_OK;
}
nsresult
nsXULCommandDispatcher::Blur(nsIDOMEvent* aEvent)
{
if (mSuppressFocus)
return NS_OK;
nsCOMPtr<nsIDOMEventTarget> t;
aEvent->GetOriginalTarget(getter_AddRefs(t));
#if 0
printf("%d : Blur occurred on: ", this);
nsCOMPtr<nsIDOMElement> domDebugElement = do_QueryInterface(t);
if (domDebugElement) {
printf("A Focusable DOM Element");
}
nsCOMPtr<nsIDOMDocument> domDebugDocument = do_QueryInterface(t);
if (domDebugDocument) {
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(t);
if (htmlDoc) {
printf("Window with an HTML doc (happens twice)");
}
else printf("Window with a XUL doc (happens twice)");
}
printf("\n");
#endif /* DEBUG_hyatt */
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(t);
if (domElement) {
SetFocusedElement(nsnull);
}
nsCOMPtr<nsIDOMWindowInternal> domWindow;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(t);
if (domDoc) {
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
if (domWindow)
SetFocusedWindow(nsnull);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// nsIScriptObjectOwner interface
NS_IMETHODIMP
nsXULCommandDispatcher::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptXULCommandDispatcher(aContext, (nsISupports *)(nsIDOMXULCommandDispatcher*)this, global, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
if (nsnull == mScriptObject) {
res = NS_NewScriptXULCommandDispatcher(aContext, (nsISupports *)(nsIDOMXULCommandDispatcher*)this, global, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return res;
NS_RELEASE(global);
return res;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
mScriptObject = aScriptObject;
return NS_OK;
}
@ -504,162 +375,41 @@ PRBool
nsXULCommandDispatcher::Matches(const nsString& aList,
const nsAReadableString& aElement)
{
if (aList.Equals(NS_LITERAL_STRING("*")))
return PR_TRUE; // match _everything_!
if (aList.Equals(NS_LITERAL_STRING("*")))
return PR_TRUE; // match _everything_!
PRInt32 indx = aList.Find((const PRUnichar *)nsPromiseFlatString(aElement).get());
if (indx == -1)
return PR_FALSE; // not in the list at all
PRInt32 indx = aList.Find((const PRUnichar *)nsPromiseFlatString(aElement).get());
if (indx == -1)
return PR_FALSE; // not in the list at all
// okay, now make sure it's not a substring snafu; e.g., 'ur'
// found inside of 'blur'.
if (indx > 0) {
PRUnichar ch = aList[indx - 1];
if (! nsCRT::IsAsciiSpace(ch) && ch != PRUnichar(','))
return PR_FALSE;
}
// okay, now make sure it's not a substring snafu; e.g., 'ur'
// found inside of 'blur'.
if (indx > 0) {
PRUnichar ch = aList[indx - 1];
if (! nsCRT::IsAsciiSpace(ch) && ch != PRUnichar(','))
return PR_FALSE;
}
if (indx + aElement.Length() < aList.Length()) {
PRUnichar ch = aList[indx + aElement.Length()];
if (! nsCRT::IsAsciiSpace(ch) && ch != PRUnichar(','))
return PR_FALSE;
}
if (indx + aElement.Length() < aList.Length()) {
PRUnichar ch = aList[indx + aElement.Length()];
if (! nsCRT::IsAsciiSpace(ch) && ch != PRUnichar(','))
return PR_FALSE;
}
return PR_TRUE;
return PR_TRUE;
}
nsresult
nsXULCommandDispatcher::GetParentWindowFromDocument(nsIDOMDocument* aDocument, nsIDOMWindowInternal** aWindow)
NS_IMETHODIMP
nsXULCommandDispatcher::GetControllers(nsIControllers** aResult)
{
nsCOMPtr<nsIDocument> objectOwner = do_QueryInterface(aDocument);
if(!objectOwner) return NS_OK;
nsCOMPtr<nsIScriptGlobalObject> globalObject;
objectOwner->GetScriptGlobalObject(getter_AddRefs(globalObject));
if(!globalObject) return NS_OK;
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(globalObject);
*aWindow = domWindow;
NS_IF_ADDREF(*aWindow);
return NS_OK;
EnsureFocusController();
return mFocusController->GetControllers(aResult);
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetControllerForCommand(const nsAReadableString& aCommand, nsIController** _retval)
{
nsPromiseFlatString flatCommand(aCommand);
const PRUnichar *command = flatCommand.get();
*_retval = nsnull;
nsCOMPtr<nsIControllers> controllers;
GetControllers(getter_AddRefs(controllers));
if(controllers) {
nsCOMPtr<nsIController> controller;
controllers->GetControllerForCommand(command, getter_AddRefs(controller));
if(controller) {
*_retval = controller;
NS_ADDREF(*_retval);
return NS_OK;
}
}
nsCOMPtr<nsPIDOMWindow> currentWindow;
if (mCurrentElement) {
// Move up to the window.
nsCOMPtr<nsIDOMDocument> domDoc;
mCurrentElement->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMWindowInternal> domWindow;
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
currentWindow = do_QueryInterface(domWindow);
}
else if (mCurrentWindow) {
nsCOMPtr<nsPIDOMWindow> privateWin = do_QueryInterface(mCurrentWindow);
privateWin->GetPrivateParent(getter_AddRefs(currentWindow));
}
else return NS_OK;
while(currentWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(currentWindow);
if(domWindow) {
nsCOMPtr<nsIControllers> controllers2;
domWindow->GetControllers(getter_AddRefs(controllers2));
if(controllers2) {
nsCOMPtr<nsIController> controller;
controllers2->GetControllerForCommand(command, getter_AddRefs(controller));
if(controller) {
*_retval = controller;
NS_ADDREF(*_retval);
return NS_OK;
}
}
}
nsCOMPtr<nsPIDOMWindow> parentPWindow = currentWindow;
parentPWindow->GetPrivateParent(getter_AddRefs(currentWindow));
}
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetSuppressFocusScroll(PRBool* aSuppressFocusScroll)
{
*aSuppressFocusScroll = mSuppressFocusScroll;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetSuppressFocusScroll(PRBool aSuppressFocusScroll)
{
mSuppressFocusScroll = aSuppressFocusScroll;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetSuppressFocus(PRBool* aSuppressFocus)
{
if(mSuppressFocus)
*aSuppressFocus = PR_TRUE;
else
*aSuppressFocus = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetSuppressFocus(PRBool aSuppressFocus)
{
if(aSuppressFocus)
++mSuppressFocus;
else if(mSuppressFocus > 0)
--mSuppressFocus;
//printf("mSuppressFocus == %d\n", mSuppressFocus);
// we are unsuppressing after activating, so update focus-related commands
// we need this to update commands in the case where an element is focussed.
if (!mSuppressFocus && mCurrentElement)
UpdateCommands(NS_LITERAL_STRING("focus"));
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetActive(PRBool* aActive)
{
//if(!mFocusInitialized)
// return PR_TRUE;
*aActive = mActive;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetActive(PRBool aActive)
{
if(!mFocusInitialized)
mFocusInitialized = PR_TRUE;
mActive = aActive;
return NS_OK;
EnsureFocusController();
return mFocusController->GetControllerForCommand(aCommand, _retval);
}

Просмотреть файл

@ -42,21 +42,22 @@
class nsIDOMElement;
class nsPIDOMWindow;
class nsIFocusController;
class nsXULCommandDispatcher : public nsIDOMXULCommandDispatcher,
public nsIDOMFocusListener,
public nsIScriptObjectOwner,
public nsSupportsWeakReference
{
protected:
nsXULCommandDispatcher(void);
virtual ~nsXULCommandDispatcher(void);
nsXULCommandDispatcher(nsIDocument* aDocument);
virtual ~nsXULCommandDispatcher();
void EnsureFocusController();
public:
static NS_IMETHODIMP
Create(nsIDOMXULCommandDispatcher** aResult);
Create(nsIDocument* aDocument, nsIDOMXULCommandDispatcher** aResult);
// nsISupports
NS_DECL_ISUPPORTS
@ -64,50 +65,31 @@ public:
// nsIDOMXULCommandDispatcher interface
NS_DECL_IDOMXULCOMMANDDISPATCHER
// nsIDOMFocusListener
virtual nsresult Focus(nsIDOMEvent* aEvent);
virtual nsresult Blur(nsIDOMEvent* aEvent);
// nsIDOMEventListener
virtual nsresult HandleEvent(nsIDOMEvent* anEvent) { return NS_OK; };
// nsIScriptObjectOwner interface
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
public:
static nsresult GetParentWindowFromDocument(nsIDOMDocument* aElement, nsIDOMWindowInternal** aWindow);
protected:
void* mScriptObject; // ????
nsIFocusController* mFocusController; // Weak. We always die before the focus controller does.
nsIDocument* mDocument; // Weak.
// XXX THis was supposed to be WEAK, but c'mon, that's an accident
// waiting to happen! If somebody deletes the node, then asks us
// for the focus, we'll get killed!
nsCOMPtr<nsIDOMElement> mCurrentElement; // [OWNER]
nsCOMPtr<nsIDOMWindowInternal> mCurrentWindow; // [OWNER]
//PRBool mSuppressFocus;
PRUint32 mSuppressFocus;
PRBool mSuppressFocusScroll;
PRBool mActive;
PRBool mFocusInitialized;
void* mScriptObject;
class Updater {
public:
Updater(nsIDOMElement* aElement,
const nsAReadableString& aEvents,
const nsAReadableString& aTargets)
: mElement(aElement),
mEvents(aEvents),
mTargets(aTargets),
mNext(nsnull)
{}
Updater(nsIDOMElement* aElement,
const nsAReadableString& aEvents,
const nsAReadableString& aTargets)
: mElement(aElement),
mEvents(aEvents),
mTargets(aTargets),
mNext(nsnull)
{}
nsIDOMElement* mElement; // [WEAK]
nsString mEvents;
nsString mTargets;
Updater* mNext;
nsIDOMElement* mElement; // [WEAK]
nsString mEvents;
nsString mTargets;
Updater* mNext;
};
Updater* mUpdaters;

Просмотреть файл

@ -1413,11 +1413,6 @@ nsXULDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
if (mRootContent)
mRootContent->SetDocument(nsnull, PR_TRUE, PR_TRUE);
// Break circular reference for the case where the currently
// focused window is ourself.
if (mCommandDispatcher)
mCommandDispatcher->SetFocusedWindow(nsnull);
// set all builder references to document to nsnull -- out of band notification
// to break ownership cycle
if (mBuilders) {
@ -3828,18 +3823,9 @@ nsXULDocument::Init()
mNodeInfoManager->Init(mNameSpaceManager);
// Create our command dispatcher and hook it up.
rv = nsXULCommandDispatcher::Create(getter_AddRefs(mCommandDispatcher));
rv = nsXULCommandDispatcher::Create(this, getter_AddRefs(mCommandDispatcher));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a focus tracker");
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMEventListener> commandDispatcher =
do_QueryInterface(mCommandDispatcher);
if (commandDispatcher) {
// Take the focus tracker and add it as an event listener for focus and blur events.
AddEventListener(NS_LITERAL_STRING("focus"), commandDispatcher, PR_TRUE);
AddEventListener(NS_LITERAL_STRING("blur"), commandDispatcher, PR_TRUE);
}
// Get the local store. Yeah, I know. I wish GetService() used a
// 'void**', too.

Просмотреть файл

@ -81,11 +81,7 @@
#include "nsCExternalHandlerService.h"
#include "nsIExternalProtocolService.h"
// XXX Very unfortunate dependencies. These are required to fix
// some serious focus bugs. Please read my comment in
// SetupNewViewer. -- hyatt
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIFocusController.h"
static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID);
static NS_DEFINE_CID(kPlatformCharsetCID, NS_PLATFORMCHARSET_CID);
@ -1681,6 +1677,15 @@ NS_IMETHODIMP nsDocShell::Destroy()
if(docShellParentAsNode)
docShellParentAsNode->RemoveChild(this);
if (mScriptGlobal) {
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(mScriptGlobal);
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
focusController->SetFocusedWindow(nsnull);
}
}
mContentViewer = nsnull;
DestroyChildren();
@ -2811,39 +2816,24 @@ NS_IMETHODIMP nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer)
}
}
// XXX The command dispatcher is the only object that understands
// focus in our system truly, madly, and deeply. Right now it is attached to
// XUL documents, but eventually it will move into the embedding layer and be
// divorced from XUL.
//
// For 6.0, however, this isn't going to happen.
//
// It is necessary to obtain the command dispatcher to utilize its ability
// It is necessary to obtain the focus controller to utilize its ability
// to suppress focus. This is necessary to fix Win32-only bugs related to
// a loss of focus when mContentViewer is set to null. The internal window
// is destroyed, and the OS focuses the parent window. This call ends up
// notifying the command dispatcher that the outer window should focus
// notifying the focus controller that the outer window should focus
// and this hoses us on any link traversal.
//
// Please do not touch any of the command dispatcher code here without
// Please do not touch any of the focus controller code here without
// testing bugs #28580 and 50509. These are immensely important bugs,
// so PLEASE take care not to regress them if you decide to alter this
// code later -- hyatt
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIFocusController> focusController;
if (mScriptGlobal) {
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(mScriptGlobal);
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
// Suppress the command dispatcher.
commandDispatcher->SetSuppressFocus(PR_TRUE);
}
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
// Suppress the command dispatcher.
focusController->SetSuppressFocus(PR_TRUE);
}
}
@ -2856,12 +2846,10 @@ NS_IMETHODIMP nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer)
mContentViewer = nsnull;
// End copying block (Don't hold content/document viewer ref beyond here!!)
// See the book I wrote above regarding why the command dispatcher is
// being used here. I reiterate that this object is not really a XUL
// object and will move post-6.0, so please don't come into my cube
// and beat me for checking this in. -- hyatt
if (commandDispatcher)
commandDispatcher->SetSuppressFocus(PR_FALSE);
// See the book I wrote above regarding why the focus controller is
// being used here. -- hyatt
if (focusController)
focusController->SetSuppressFocus(PR_FALSE);
mContentViewer = aNewViewer;

Просмотреть файл

@ -35,6 +35,8 @@ nsIDOMPluginArray.h
nsIDOMBarProp.h
nsIDOMDOMException.h
nsPIDOMWindow.h
nsPIWindowRoot.h
nsIFocusController.h
nsIDOMAbstractView.h
nsIDOMCrypto.h
nsIDOMCRMFObject.h

Просмотреть файл

@ -44,6 +44,8 @@ EXPORTS = \
nsIDOMBarProp.h \
nsIDOMDOMException.h \
nsPIDOMWindow.h \
nsPIWindowRoot.h \
nsIFocusController.h \
nsIDOMAbstractView.h \
nsIDOMViewCSS.h \
nsIDOMCRMFObject.h \

Просмотреть файл

@ -28,9 +28,9 @@ EXPORTS=nsIDOMWindow.h nsIDOMWindowInternal.h nsIDOMNavigator.h \
nsIDOMWindowCollection.h nsIDOMScreen.h nsIDOMHistory.h \
nsIDOMMimeType.h nsIDOMMimeTypeArray.h \
nsIDOMPlugin.h nsIDOMPluginArray.h nsIDOMBarProp.h \
nsIDOMDOMException.h nsPIDOMWindow.h nsIDOMAbstractView.h \
nsIDOMDOMException.h nsPIDOMWindow.h nsPIWindowRoot.h nsIDOMAbstractView.h \
nsIDOMViewCSS.h nsIDOMCRMFObject.h nsIDOMCrypto.h nsIDOMPkcs11.h \
nsIDOMWindowEventOwner.h
nsIDOMWindowEventOwner.h nsIFocusController.h
MODULE=dom

Просмотреть файл

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Contributor(s):
* David W. Hyatt <hyatt@netscape.com> (Original Author)
*/
#ifndef nsIFocusController_h__
#define nsIFocusController_h__
#include "nsISupports.h"
class nsIDOMElement;
class nsIDOMWindowInternal;
class nsIController;
class nsIControllers;
// {AC71F479-17E1-4ee0-8EFD-0ECF2AA2F827}
#define NS_IFOCUSCONTROLLER_IID \
{ 0xac71f479, 0x17e1, 0x4ee0, { 0x8e, 0xfd, 0xe, 0xcf, 0x2a, 0xa2, 0xf8, 0x27 } }
class nsIFocusController : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IFOCUSCONTROLLER_IID; return iid; }
NS_IMETHOD GetFocusedElement(nsIDOMElement** aResult)=0;
NS_IMETHOD SetFocusedElement(nsIDOMElement* aElement)=0;
NS_IMETHOD GetFocusedWindow(nsIDOMWindowInternal** aResult)=0;
NS_IMETHOD SetFocusedWindow(nsIDOMWindowInternal* aResult)=0;
NS_IMETHOD GetSuppressFocus(PRBool* aSuppressFlag)=0;
NS_IMETHOD SetSuppressFocus(PRBool aSuppressFlag)=0;
NS_IMETHOD GetSuppressFocusScroll(PRBool* aSuppressFlag)=0;
NS_IMETHOD SetSuppressFocusScroll(PRBool aSuppressFlag)=0;
NS_IMETHOD GetActive(PRBool* aActive)=0;
NS_IMETHOD SetActive(PRBool aActive)=0;
NS_IMETHOD GetControllerForCommand(const nsAReadableString& aCommand, nsIController** aResult)=0;
NS_IMETHOD GetControllers(nsIControllers** aResult)=0;
};
#endif // nsIFocusController_h__

Просмотреть файл

@ -34,6 +34,8 @@
class nsIDocShell;
class nsIDOMWindowInternal;
class nsIChromeEventHandler;
class nsIFocusController;
#define NS_PIDOMWINDOW_IID \
{ 0x3aa80781, 0x7e6a, 0x11d3, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
@ -55,7 +57,9 @@ public:
NS_IMETHOD Activate() = 0;
NS_IMETHOD Deactivate() = 0;
NS_IMETHOD GetRootCommandDispatcher(nsIDOMXULCommandDispatcher ** aDispatcher)=0;
NS_IMETHOD GetChromeEventHandler(nsIChromeEventHandler** aHandler)=0;
NS_IMETHOD GetRootFocusController(nsIFocusController** aResult)=0;
/* from nsIBaseWindow */
/* void setPositionAndSize (in long x, in long y, in long cx, in long cy, in boolean fRepaint); */

Просмотреть файл

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Contributor(s):
* David W. Hyatt <hyatt@netscape.com> (Original Author)
*/
#ifndef nsPIWindowRoot_h__
#define nsPIWindowRoot_h__
#include "nsISupports.h"
class nsIFocusController;
// {575CB0E1-E6C4-484a-99F8-C47B06C0E521}
#define NS_IWINDOWROOT_IID \
{ 0x575cb0e1, 0xe6c4, 0x484a, { 0x99, 0xf8, 0xc4, 0x7b, 0x6, 0xc0, 0xe5, 0x21 } }
class nsPIWindowRoot : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IWINDOWROOT_IID; return iid; }
NS_IMETHOD GetFocusController(nsIFocusController** aResult)=0;
};
#endif // nsPIWindowRoot_h__

Просмотреть файл

@ -5,9 +5,6 @@ interface XULCommandDispatcher {
attribute Element focusedElement;
attribute WindowInternal focusedWindow;
attribute boolean suppressFocus;
attribute boolean suppressFocusScroll;
attribute boolean active;
void addCommandUpdater(in Element updater, in DOMString events, in DOMString targets);
void removeCommandUpdater(in Element updater);
@ -15,6 +12,5 @@ interface XULCommandDispatcher {
void updateCommands(in DOMString eventName);
xpidl nsIController getControllerForCommand(in DOMString command);
xpidl nsIControllers getControllers();
};

Просмотреть файл

@ -47,15 +47,6 @@ public:
NS_IMETHOD GetFocusedWindow(nsIDOMWindowInternal** aFocusedWindow)=0;
NS_IMETHOD SetFocusedWindow(nsIDOMWindowInternal* aFocusedWindow)=0;
NS_IMETHOD GetSuppressFocus(PRBool* aSuppressFocus)=0;
NS_IMETHOD SetSuppressFocus(PRBool aSuppressFocus)=0;
NS_IMETHOD GetSuppressFocusScroll(PRBool* aSuppressFocusScroll)=0;
NS_IMETHOD SetSuppressFocusScroll(PRBool aSuppressFocusScroll)=0;
NS_IMETHOD GetActive(PRBool* aActive)=0;
NS_IMETHOD SetActive(PRBool aActive)=0;
NS_IMETHOD AddCommandUpdater(nsIDOMElement* aUpdater, const nsAReadableString& aEvents, const nsAReadableString& aTargets)=0;
NS_IMETHOD RemoveCommandUpdater(nsIDOMElement* aUpdater)=0;
@ -73,12 +64,6 @@ public:
NS_IMETHOD SetFocusedElement(nsIDOMElement* aFocusedElement); \
NS_IMETHOD GetFocusedWindow(nsIDOMWindowInternal** aFocusedWindow); \
NS_IMETHOD SetFocusedWindow(nsIDOMWindowInternal* aFocusedWindow); \
NS_IMETHOD GetSuppressFocus(PRBool* aSuppressFocus); \
NS_IMETHOD SetSuppressFocus(PRBool aSuppressFocus); \
NS_IMETHOD GetSuppressFocusScroll(PRBool* aSuppressFocusScroll); \
NS_IMETHOD SetSuppressFocusScroll(PRBool aSuppressFocusScroll); \
NS_IMETHOD GetActive(PRBool* aActive); \
NS_IMETHOD SetActive(PRBool aActive); \
NS_IMETHOD AddCommandUpdater(nsIDOMElement* aUpdater, const nsAReadableString& aEvents, const nsAReadableString& aTargets); \
NS_IMETHOD RemoveCommandUpdater(nsIDOMElement* aUpdater); \
NS_IMETHOD UpdateCommands(const nsAReadableString& aEventName); \
@ -92,12 +77,6 @@ public:
NS_IMETHOD SetFocusedElement(nsIDOMElement* aFocusedElement) { return _to SetFocusedElement(aFocusedElement); } \
NS_IMETHOD GetFocusedWindow(nsIDOMWindowInternal** aFocusedWindow) { return _to GetFocusedWindow(aFocusedWindow); } \
NS_IMETHOD SetFocusedWindow(nsIDOMWindowInternal* aFocusedWindow) { return _to SetFocusedWindow(aFocusedWindow); } \
NS_IMETHOD GetSuppressFocus(PRBool* aSuppressFocus) { return _to GetSuppressFocus(aSuppressFocus); } \
NS_IMETHOD SetSuppressFocus(PRBool aSuppressFocus) { return _to SetSuppressFocus(aSuppressFocus); } \
NS_IMETHOD GetSuppressFocusScroll(PRBool* aSuppressFocusScroll) { return _to GetSuppressFocusScroll(aSuppressFocusScroll); } \
NS_IMETHOD SetSuppressFocusScroll(PRBool aSuppressFocusScroll) { return _to SetSuppressFocusScroll(aSuppressFocusScroll); } \
NS_IMETHOD GetActive(PRBool* aActive) { return _to GetActive(aActive); } \
NS_IMETHOD SetActive(PRBool aActive) { return _to SetActive(aActive); } \
NS_IMETHOD AddCommandUpdater(nsIDOMElement* aUpdater, const nsAReadableString& aEvents, const nsAReadableString& aTargets) { return _to AddCommandUpdater(aUpdater, aEvents, aTargets); } \
NS_IMETHOD RemoveCommandUpdater(nsIDOMElement* aUpdater) { return _to RemoveCommandUpdater(aUpdater); } \
NS_IMETHOD UpdateCommands(const nsAReadableString& aEventName) { return _to UpdateCommands(aEventName); } \

Просмотреть файл

@ -40,6 +40,7 @@ CPPSRCS = \
nsJSNavigator.cpp \
nsJSLocation.cpp \
nsJSWindowCollection.cpp \
nsFocusController.cpp \
nsGlobalWindow.cpp \
nsLocation.cpp \
nsDOMWindowList.cpp \
@ -57,6 +58,7 @@ CPPSRCS = \
nsJSCRMFObject.cpp \
nsJSCrypto.cpp \
nsJSPkcs11.cpp \
nsWindowRoot.cpp \
$(NULL)
EXPORTS = nsJSUtils.h

Просмотреть файл

@ -36,6 +36,7 @@ CPPSRCS = \
nsJSNavigator.cpp \
nsJSLocation.cpp \
nsJSWindowCollection.cpp \
nsFocusController.cpp \
nsGlobalWindow.cpp \
nsLocation.cpp \
nsDOMWindowList.cpp \
@ -53,6 +54,7 @@ CPPSRCS = \
nsJSCrypto.cpp \
nsJSCMRFObject.cpp \
nsJSPkcs11.cpp \
nsWindowRoot.cpp \
$(NULL)
EXPORTS=nsJSUtils.h
@ -67,6 +69,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsJSDOMException.obj \
.\$(OBJDIR)\nsJSEnvironment.obj \
.\$(OBJDIR)\nsJSWindow.obj \
.\$(OBJDIR)\nsFocusController.obj \
.\$(OBJDIR)\nsGlobalWindow.obj \
.\$(OBJDIR)\nsJSNavigator.obj \
.\$(OBJDIR)\nsLocation.obj \
@ -87,6 +90,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsJSCrypto.obj \
.\$(OBJDIR)\nsJSCRMFObject.obj \
.\$(OBJDIR)\nsJSPkcs11.obj \
.\$(OBJDIR)\nsWindowRoot.obj \
$(NULL)
LINCS=-I$(XPDIST)\public\xpcom -I$(XPDIST)\public\raptor \

Просмотреть файл

@ -0,0 +1,369 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Contributor(s):
* David W. Hyatt <hyatt@netscape.com> (Original Author)
*/
#include "nsIContent.h"
#include "nsIControllers.h"
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMNSHTMLInputElement.h"
#include "nsIDOMNSHTMLTextAreaElement.h"
#include "nsIDOMUIEvent.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDocument.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIScriptGlobalObject.h"
#include "nsPIDOMWindow.h"
#include "nsFocusController.h"
#include "prlog.h"
#include "nsIDOMEventTarget.h"
#ifdef INCLUDE_XUL
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULElement.h"
#endif
////////////////////////////////////////////////////////////////////////
nsFocusController::nsFocusController(void)
: mSuppressFocus(0),
mSuppressFocusScroll(PR_FALSE),
mActive(PR_FALSE)
{
NS_INIT_REFCNT();
}
nsFocusController::~nsFocusController(void)
{
}
NS_IMPL_ISUPPORTS3(nsFocusController, nsIFocusController, nsIDOMFocusListener, nsIDOMEventListener)
NS_IMETHODIMP
nsFocusController::Create(nsIFocusController** aResult)
{
nsFocusController* controller = new nsFocusController();
if (!controller)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = controller;
NS_ADDREF(*aResult);
return NS_OK;
}
////////////////////////////////////////////////////////////////
// nsIFocusController Interface
NS_IMETHODIMP
nsFocusController::GetFocusedElement(nsIDOMElement** aElement)
{
*aElement = mCurrentElement;
NS_IF_ADDREF(*aElement);
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::GetFocusedWindow(nsIDOMWindowInternal** aWindow)
{
*aWindow = mCurrentWindow;
NS_IF_ADDREF(*aWindow);
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::SetFocusedElement(nsIDOMElement* aElement)
{
mCurrentElement = aElement;
// Need to update focus commands when focus switches from
// an element to no element, so don't test mCurrentElement
// before updating.
UpdateCommands(NS_LITERAL_STRING("focus"));
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::SetFocusedWindow(nsIDOMWindowInternal* aWindow)
{
mCurrentWindow = aWindow;
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::UpdateCommands(const nsAReadableString& aEventName)
{
if (mCurrentWindow) {
mCurrentWindow->UpdateCommands(aEventName);
}
else if (mCurrentElement) {
nsCOMPtr<nsIDOMDocument> domDoc;
mCurrentElement->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
nsCOMPtr<nsIScriptGlobalObject> global;
doc->GetScriptGlobalObject(getter_AddRefs(global));
nsCOMPtr<nsIDOMWindowInternal> window(do_QueryInterface(global));
window->UpdateCommands(aEventName);
}
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::GetControllers(nsIControllers** aResult)
{
//XXX: we should fix this so there's a generic interface that describes controllers,
// so this code would have no special knowledge of what object might have controllers.
if (mCurrentElement) {
#ifdef INCLUDE_XUL
nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(mCurrentElement));
if (xulElement)
return xulElement->GetControllers(aResult);
#endif
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextArea(do_QueryInterface(mCurrentElement));
if (htmlTextArea)
return htmlTextArea->GetControllers(aResult);
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement(do_QueryInterface(mCurrentElement));
if (htmlInputElement)
return htmlInputElement->GetControllers(aResult);
}
else if (mCurrentWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow(do_QueryInterface(mCurrentWindow));
if (domWindow)
return domWindow->GetControllers(aResult);
}
*aResult = nsnull;
return NS_OK;
}
/////
// nsIDOMFocusListener
/////
nsresult
nsFocusController::Focus(nsIDOMEvent* aEvent)
{
if (mSuppressFocus)
return NS_OK;
nsCOMPtr<nsIDOMEventTarget> t;
aEvent->GetOriginalTarget(getter_AddRefs(t));
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(t);
if (domElement && (domElement != mCurrentElement)) {
SetFocusedElement(domElement);
// Also set focus to our innermost window.
// XXX Must be done for the Ender case, since ender causes a blur,
// but we don't hear the subsequent focus to the Ender window.
nsCOMPtr<nsIDOMDocument> ownerDoc;
domElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
nsCOMPtr<nsIDOMWindowInternal> domWindow;
GetParentWindowFromDocument(ownerDoc, getter_AddRefs(domWindow));
if (domWindow)
SetFocusedWindow(domWindow);
}
else {
// We're focusing a window. We only want to do an update commands
// if no element is focused.
nsCOMPtr<nsIDOMWindowInternal> domWindow;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(t);
if (domDoc) {
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
if (domWindow) {
SetFocusedWindow(domWindow);
if (mCurrentElement) {
// Make sure this element is in our window. If not, we
// should clear this field.
nsCOMPtr<nsIDOMDocument> ownerDoc;
mCurrentElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
nsCOMPtr<nsIDOMDocument> windowDoc;
mCurrentWindow->GetDocument(getter_AddRefs(windowDoc));
if (ownerDoc != windowDoc)
mCurrentElement = nsnull;
}
if (!mCurrentElement)
UpdateCommands(NS_LITERAL_STRING("focus"));
}
}
}
return NS_OK;
}
nsresult
nsFocusController::Blur(nsIDOMEvent* aEvent)
{
if (mSuppressFocus)
return NS_OK;
nsCOMPtr<nsIDOMEventTarget> t;
aEvent->GetOriginalTarget(getter_AddRefs(t));
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(t);
if (domElement) {
SetFocusedElement(nsnull);
}
nsCOMPtr<nsIDOMWindowInternal> domWindow;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(t);
if (domDoc) {
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
if (domWindow)
SetFocusedWindow(nsnull);
}
return NS_OK;
}
nsresult
nsFocusController::GetParentWindowFromDocument(nsIDOMDocument* aDocument, nsIDOMWindowInternal** aWindow)
{
nsCOMPtr<nsIDocument> objectOwner = do_QueryInterface(aDocument);
if(!objectOwner) return NS_OK;
nsCOMPtr<nsIScriptGlobalObject> globalObject;
objectOwner->GetScriptGlobalObject(getter_AddRefs(globalObject));
if(!globalObject) return NS_OK;
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(globalObject);
*aWindow = domWindow;
NS_IF_ADDREF(*aWindow);
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::GetControllerForCommand(const nsAReadableString& aCommand, nsIController** _retval)
{
nsPromiseFlatString flatCommand(aCommand);
const PRUnichar *command = flatCommand.get();
*_retval = nsnull;
nsCOMPtr<nsIControllers> controllers;
GetControllers(getter_AddRefs(controllers));
if(controllers) {
nsCOMPtr<nsIController> controller;
controllers->GetControllerForCommand(command, getter_AddRefs(controller));
if(controller) {
*_retval = controller;
NS_ADDREF(*_retval);
return NS_OK;
}
}
nsCOMPtr<nsPIDOMWindow> currentWindow;
if (mCurrentElement) {
// Move up to the window.
nsCOMPtr<nsIDOMDocument> domDoc;
mCurrentElement->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMWindowInternal> domWindow;
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
currentWindow = do_QueryInterface(domWindow);
}
else if (mCurrentWindow) {
nsCOMPtr<nsPIDOMWindow> privateWin = do_QueryInterface(mCurrentWindow);
privateWin->GetPrivateParent(getter_AddRefs(currentWindow));
}
else return NS_OK;
while(currentWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(currentWindow);
if(domWindow) {
nsCOMPtr<nsIControllers> controllers2;
domWindow->GetControllers(getter_AddRefs(controllers2));
if(controllers2) {
nsCOMPtr<nsIController> controller;
controllers2->GetControllerForCommand(command, getter_AddRefs(controller));
if(controller) {
*_retval = controller;
NS_ADDREF(*_retval);
return NS_OK;
}
}
}
nsCOMPtr<nsPIDOMWindow> parentPWindow = currentWindow;
parentPWindow->GetPrivateParent(getter_AddRefs(currentWindow));
}
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::GetSuppressFocusScroll(PRBool* aSuppressFocusScroll)
{
*aSuppressFocusScroll = mSuppressFocusScroll;
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::SetSuppressFocusScroll(PRBool aSuppressFocusScroll)
{
mSuppressFocusScroll = aSuppressFocusScroll;
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::GetSuppressFocus(PRBool* aSuppressFocus)
{
*aSuppressFocus = (mSuppressFocus > 0);
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::SetSuppressFocus(PRBool aSuppressFocus)
{
if(aSuppressFocus)
++mSuppressFocus;
else if(mSuppressFocus > 0)
--mSuppressFocus;
// we are unsuppressing after activating, so update focus-related commands
// we need this to update commands in the case where an element is focused.
if (!mSuppressFocus && mCurrentElement)
UpdateCommands(NS_LITERAL_STRING("focus"));
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::GetActive(PRBool* aActive)
{
*aActive = mActive;
return NS_OK;
}
NS_IMETHODIMP
nsFocusController::SetActive(PRBool aActive)
{
mActive = aActive;
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,91 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Contributor(s):
* David W. Hyatt <hyatt@netscape.com> (Original Author)
*/
#ifndef nsFocusController_h__
#define nsFocusController_h__
#include "nsCOMPtr.h"
#include "nsIFocusController.h"
#include "nsIDOMFocusListener.h"
#include "nsIDOMElement.h"
#include "nsIDOMWindow.h"
class nsIDOMElement;
class nsIDOMWindow;
class nsIController;
class nsIControllers;
class nsFocusController : public nsIFocusController,
public nsIDOMFocusListener
{
public:
static NS_IMETHODIMP Create(nsIFocusController** aResult);
protected:
nsFocusController(void);
virtual ~nsFocusController(void);
public:
NS_DECL_ISUPPORTS
NS_IMETHOD GetFocusedElement(nsIDOMElement** aResult);
NS_IMETHOD SetFocusedElement(nsIDOMElement* aElement);
NS_IMETHOD GetFocusedWindow(nsIDOMWindowInternal** aResult);
NS_IMETHOD SetFocusedWindow(nsIDOMWindowInternal* aResult);
NS_IMETHOD GetSuppressFocus(PRBool* aSuppressFlag);
NS_IMETHOD SetSuppressFocus(PRBool aSuppressFlag);
NS_IMETHOD GetSuppressFocusScroll(PRBool* aSuppressFlag);
NS_IMETHOD SetSuppressFocusScroll(PRBool aSuppressFlag);
NS_IMETHOD GetActive(PRBool* aActive);
NS_IMETHOD SetActive(PRBool aActive);
NS_IMETHOD GetControllerForCommand(const nsAReadableString& aCommand, nsIController** aResult);
NS_IMETHOD GetControllers(nsIControllers** aResult);
// nsIDOMFocusListener
virtual nsresult Focus(nsIDOMEvent* aEvent);
virtual nsresult Blur(nsIDOMEvent* aEvent);
// nsIDOMEventListener
virtual nsresult HandleEvent(nsIDOMEvent* anEvent) { return NS_OK; };
protected:
NS_IMETHOD UpdateCommands(const nsAReadableString& aEventName);
public:
static nsresult GetParentWindowFromDocument(nsIDOMDocument* aElement, nsIDOMWindowInternal** aWindow);
// Members
protected:
nsCOMPtr<nsIDOMElement> mCurrentElement; // [OWNER]
nsCOMPtr<nsIDOMWindowInternal> mCurrentWindow; // [OWNER]
PRUint32 mSuppressFocus;
PRBool mSuppressFocusScroll;
PRBool mActive;
};
#endif // nsFocusController_h__

Просмотреть файл

@ -102,6 +102,8 @@
#include "nsDOMCID.h"
#include "nsDOMError.h"
#include "nsWindowRoot.h"
// XXX An unfortunate dependency exists here (two XUL files).
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULCommandDispatcher.h"
@ -306,12 +308,12 @@ NS_IMETHODIMP GlobalWindowImpl::SetNewDocument(nsIDOMDocument* aDocument)
// browser scrolling and other browser commands.
nsCOMPtr<nsIDOMWindowInternal> internal;
GetPrivateRoot(getter_AddRefs(internal));
nsCOMPtr<nsIDOMWindowInternal> us(do_QueryInterface((nsIDOMWindow*)this));
nsCOMPtr<nsIDOMWindowInternal> us(do_QueryInterface(NS_STATIC_CAST(nsIDOMWindow*,this)));
if (internal == us) {
nsresult rv;
NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv);
if (xblService) {
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(internal));
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(mChromeEventHandler));
xblService->AttachGlobalKeyHandler(rec);
}
}
@ -434,10 +436,23 @@ NS_IMETHODIMP GlobalWindowImpl::SetDocShell(nsIDocShell* aDocShell)
// Get our enclosing chrome shell and retrieve its global window impl, so
// that we can do some forwarding to the chrome document.
nsCOMPtr<nsIChromeEventHandler> chromeEventHandler;
mDocShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
if (chromeEventHandler)
mChromeEventHandler = chromeEventHandler.get(); // ref
mDocShell->GetChromeEventHandler(getter_AddRefs(mChromeEventHandler));
if (!mChromeEventHandler) {
// We have no chrome event handler. If we have a parent,
// get our chrome event handler from the parent. If
// we don't have a parent, then we need to make a new
// window root object that will function as a chrome event
// handler and receive all events that occur anywhere inside
// our window.
nsCOMPtr<nsIDOMWindow> parentWindow;
GetParent(getter_AddRefs(parentWindow));
if (parentWindow.get() != NS_STATIC_CAST(nsIDOMWindow*,this)) {
nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(parentWindow));
nsCOMPtr<nsIChromeEventHandler> handler;
piWindow->GetChromeEventHandler(getter_AddRefs(mChromeEventHandler));
}
else NS_NewWindowRoot(this, getter_AddRefs(mChromeEventHandler));
}
}
return NS_OK;
}
@ -2098,48 +2113,23 @@ NS_IMETHODIMP GlobalWindowImpl::Close(JSContext* cx, jsval* argv, PRUint32 argc)
NS_IMETHODIMP GlobalWindowImpl::UpdateCommands(const nsAReadableString& anAction)
{
if (mChromeEventHandler) {
// Just jump out to the chrome event handler.
nsCOMPtr<nsIContent> content = do_QueryInterface(mChromeEventHandler);
if (content) {
// Cross the chrome/content boundary and get the nearest enclosing
// chrome window.
nsCOMPtr<nsIDocument> doc;
content->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIScriptGlobalObject> global;
if (!doc)
return NS_ERROR_NULL_POINTER;
doc->GetScriptGlobalObject(getter_AddRefs(global));
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(global);
return domWindow->UpdateCommands(anAction);
}
else {
// XXX Handle the embedding case. The chrome handler could be told
// to poke menu items/update commands etc. This can be used by
// embedders if we set it up right and lets them know all sorts of
// interesting things about Ender text fields.
}
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
GetPrivateRoot(getter_AddRefs(rootWindow));
if (!rootWindow)
return NS_OK;
}
else {
nsCOMPtr<nsIDOMDocument> document;
rootWindow->GetDocument(getter_AddRefs(document));
if (document) {
// See if we contain a XUL document.
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(mDocument);
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(document);
if (xulDoc) {
// Retrieve the command dispatcher and call updateCommands on it.
nsCOMPtr<nsIDOMXULCommandDispatcher> xulCommandDispatcher;
xulDoc->GetCommandDispatcher(getter_AddRefs(xulCommandDispatcher));
xulCommandDispatcher->UpdateCommands(anAction);
}
// Now call UpdateCommands on our parent window.
nsCOMPtr<nsIDOMWindow> parent;
GetParent(getter_AddRefs(parent));
// GetParent returns self at the top
if (NS_STATIC_CAST(nsIDOMWindow *, this) == parent.get())
return NS_OK;
nsCOMPtr<nsIDOMWindowInternal> parentInternal = do_QueryInterface(parent);
return parentInternal->UpdateCommands(anAction);
}
return NS_OK;
@ -2597,6 +2587,10 @@ NS_IMETHODIMP GlobalWindowImpl::GetPrivateRoot(nsIDOMWindowInternal ** aParent)
if(parentTop == nsnull)
return NS_ERROR_FAILURE;
parentTop->GetDocShell(getter_AddRefs(docShell));
// Get the chrome event handler from the doc shell, since we only
// want to deal with XUL chrome handlers and not the new kind of
// window root handler.
nsCOMPtr<nsIChromeEventHandler> chromeEventHandler;
docShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
@ -2806,31 +2800,35 @@ NS_IMETHODIMP GlobalWindowImpl::Deactivate()
}
NS_IMETHODIMP
GlobalWindowImpl::GetRootCommandDispatcher(nsIDOMXULCommandDispatcher **
aDispatcher)
GlobalWindowImpl::GetChromeEventHandler(nsIChromeEventHandler** aHandler)
{
if (!aDispatcher)
return NS_ERROR_FAILURE;
*aDispatcher = nsnull;
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
GetPrivateRoot(getter_AddRefs(rootWindow));
if (rootWindow) {
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
xulDoc->GetCommandDispatcher(aDispatcher);
}
}
*aHandler = mChromeEventHandler;
NS_IF_ADDREF(*aHandler);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetRootFocusController(nsIFocusController** aController)
{
*aController = nsnull;
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
GetPrivateRoot(getter_AddRefs(rootWindow));
if (rootWindow) {
// Obtain the chrome event handler.
nsCOMPtr<nsIChromeEventHandler> chromeHandler;
nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(rootWindow));
piWin->GetChromeEventHandler(getter_AddRefs(chromeHandler));
if (chromeHandler) {
nsCOMPtr<nsPIWindowRoot> windowRoot(do_QueryInterface(chromeHandler));
if (windowRoot) {
windowRoot->GetFocusController(getter_AddRefs(aController));
}
}
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetPositionAndSize(PRInt32 x, PRInt32 y, PRInt32 cx,

Просмотреть файл

@ -159,7 +159,9 @@ public:
NS_IMETHOD Activate();
NS_IMETHOD Deactivate();
NS_IMETHOD GetRootCommandDispatcher(nsIDOMXULCommandDispatcher ** aDispatcher);
NS_IMETHOD GetChromeEventHandler(nsIChromeEventHandler** aHandler);
NS_IMETHOD GetRootFocusController(nsIFocusController** aResult);
NS_IMETHOD SetPositionAndSize(PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy, PRBool fRepaint);
@ -252,7 +254,7 @@ protected:
nsIScriptGlobalObjectOwner* mGlobalObjectOwner; // Weak Reference
nsIDocShell* mDocShell; // Weak Reference
nsIChromeEventHandler* mChromeEventHandler; // Weak Reference
nsCOMPtr<nsIChromeEventHandler> mChromeEventHandler; // [Strong] We break it when we get torn down.
nsCOMPtr<nsIDOMCrypto> mCrypto;
nsCOMPtr<nsIDOMPkcs11> mPkcs11;
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;

Просмотреть файл

@ -0,0 +1,229 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Contributor(s):
* David W. Hyatt <hyatt@netscape.com> (Original Author)
*/
#include "nsCOMPtr.h"
#include "nsWindowRoot.h"
#include "nsIDOMWindow.h"
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsIEventListenerManager.h"
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#include "nsLayoutCID.h"
#include "nsIEventStateManager.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIDOMWindowInternal.h"
#include "nsFocusController.h"
static NS_DEFINE_CID(kEventListenerManagerCID, NS_EVENTLISTENERMANAGER_CID);
nsWindowRoot::nsWindowRoot(nsIDOMWindow* aWindow)
{
NS_INIT_ISUPPORTS();
mWindow = aWindow;
// Create and init our focus controller.
nsFocusController::Create(getter_AddRefs(mFocusController));
nsCOMPtr<nsIDOMFocusListener> focusListener(do_QueryInterface(mFocusController));
AddEventListener(NS_LITERAL_STRING("focus"), focusListener, PR_TRUE);
AddEventListener(NS_LITERAL_STRING("blur"), focusListener, PR_TRUE);
}
nsWindowRoot::~nsWindowRoot()
{
}
NS_IMPL_ISUPPORTS3(nsWindowRoot, nsIDOMEventReceiver, nsIChromeEventHandler, nsPIWindowRoot)
NS_IMETHODIMP
nsWindowRoot::AddEventListener(const nsAReadableString& aType, nsIDOMEventListener* aListener, PRBool aUseCapture)
{
nsCOMPtr<nsIEventListenerManager> manager;
GetListenerManager(getter_AddRefs(manager));
if (manager) {
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
manager->AddEventListenerByType(aListener, aType, flags);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsWindowRoot::RemoveEventListener(const nsAReadableString& aType, nsIDOMEventListener* aListener, PRBool aUseCapture)
{
nsCOMPtr<nsIEventListenerManager> manager;
GetListenerManager(getter_AddRefs(manager));
if (manager) {
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
manager->RemoveEventListenerByType(aListener, aType, flags);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsWindowRoot::DispatchEvent(nsIDOMEvent* aEvt)
{
// Obtain a presentation context
nsCOMPtr<nsIDOMDocument> domDoc;
mWindow->GetDocument(getter_AddRefs(domDoc));
if (!domDoc)
return NS_OK;
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
PRInt32 count = doc->GetNumberOfShells();
if (count == 0)
return NS_OK;
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(doc->GetShellAt(0));
// Retrieve the context
nsCOMPtr<nsIPresContext> aPresContext;
shell->GetPresContext(getter_AddRefs(aPresContext));
nsCOMPtr<nsIEventStateManager> esm;
if (NS_SUCCEEDED(aPresContext->GetEventStateManager(getter_AddRefs(esm)))) {
return esm->DispatchNewEvent(NS_STATIC_CAST(nsIDOMEventReceiver*,this), aEvt);
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsWindowRoot::AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> manager;
GetListenerManager(getter_AddRefs(manager));
if (manager) {
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsWindowRoot::RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> manager;
GetListenerManager(getter_AddRefs(manager));
if (manager) {
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsWindowRoot::GetListenerManager(nsIEventListenerManager** aResult)
{
if (!mListenerManager) {
nsresult rv;
mListenerManager = do_CreateInstance(kEventListenerManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
}
*aResult = mListenerManager;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsWindowRoot::GetNewListenerManager(nsIEventListenerManager **aResult)
{
return nsComponentManager::CreateInstance(kEventListenerManagerCID,
nsnull,
NS_GET_IID(nsIEventListenerManager),
(void**) aResult);
}
NS_IMETHODIMP
nsWindowRoot::HandleEvent(nsIDOMEvent *aEvent)
{
return DispatchEvent(aEvent);
}
NS_IMETHODIMP nsWindowRoot::HandleChromeEvent(nsIPresContext* aPresContext,
nsEvent* aEvent, nsIDOMEvent** aDOMEvent, PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
// Prevent the world from going
// away until after we've finished handling the event.
nsCOMPtr<nsIDOMWindow> kungFuDeathGrip(mWindow);
nsresult ret = NS_OK;
nsIDOMEvent* domEvent = nsnull;
// We're at the top, so there's no bubbling or capturing here.
if (NS_EVENT_FLAG_INIT & aFlags) {
aDOMEvent = &domEvent;
aEvent->flags = aFlags;
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
}
//Local handling stage
if (mListenerManager && !(aEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) {
aEvent->flags |= aFlags;
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, this, aFlags, aEventStatus);
aEvent->flags &= ~aFlags;
}
if (NS_EVENT_FLAG_INIT & aFlags) {
// We're leaving the DOM event loop so if we created a DOM event, release here.
if (nsnull != *aDOMEvent) {
nsrefcnt rc;
NS_RELEASE2(*aDOMEvent, rc);
if (0 != rc) {
//Okay, so someone in the DOM loop (a listener, JS object) still has a ref to the DOM Event but
//the internal data hasn't been malloc'd. Force a copy of the data here so the DOM Event is still valid.
nsIPrivateDOMEvent *privateEvent;
if (NS_OK == (*aDOMEvent)->QueryInterface(NS_GET_IID(nsIPrivateDOMEvent), (void**)&privateEvent)) {
privateEvent->DuplicatePrivateData();
NS_RELEASE(privateEvent);
}
}
}
aDOMEvent = nsnull;
}
return ret;
}
NS_IMETHODIMP
nsWindowRoot::GetFocusController(nsIFocusController** aResult)
{
*aResult = mFocusController;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////////////
nsresult
NS_NewWindowRoot(nsIDOMWindow* aWindow, nsIChromeEventHandler** aResult)
{
*aResult = new nsWindowRoot(aWindow);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Contributor(s):
* David W. Hyatt <hyatt@netscape.com> (Original Author)
*/
#ifndef nsWindowRoot_h__
#define nsWindowRoot_h__
class nsIDOMWindow;
class nsIDOMEventListener;
class nsIEventListenerManager;
class nsIDOMEvent;
#include "nsGUIEvent.h"
#include "nsIDOMEventReceiver.h"
#include "nsIChromeEventHandler.h"
#include "nsIEventListenerManager.h"
#include "nsPIWindowRoot.h"
#include "nsIFocusController.h"
class nsWindowRoot : public nsIDOMEventReceiver, public nsIChromeEventHandler, public nsPIWindowRoot
{
public:
nsWindowRoot(nsIDOMWindow* aWindow);
virtual ~nsWindowRoot();
NS_DECL_ISUPPORTS
NS_DECL_IDOMEVENTTARGET
NS_IMETHOD HandleChromeEvent(nsIPresContext* aPresContext,
nsEvent* aEvent, nsIDOMEvent** aDOMEvent, PRUint32 aFlags,
nsEventStatus* aEventStatus);
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager **aInstancePtrResult);
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
// nsPIWindowRoot
NS_IMETHOD GetFocusController(nsIFocusController** aResult);
protected:
// Members
nsIDOMWindow* mWindow; // [Weak]. The window will hold on to us and let go when it dies.
nsCOMPtr<nsIEventListenerManager> mListenerManager; // [Strong]. We own the manager, which owns event listeners attached
// to us.
nsCOMPtr<nsIFocusController> mFocusController; // The focus controller for the root.
};
extern nsresult
NS_NewWindowRoot(nsIDOMWindow* aWindow,
nsIChromeEventHandler** aResult);
#endif

Просмотреть файл

@ -55,10 +55,7 @@ static NS_DEFINE_IID(kIControllersIID, NS_ICONTROLLERS_IID);
//
enum XULCommandDispatcher_slots {
XULCOMMANDDISPATCHER_FOCUSEDELEMENT = -1,
XULCOMMANDDISPATCHER_FOCUSEDWINDOW = -2,
XULCOMMANDDISPATCHER_SUPPRESSFOCUS = -3,
XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL = -4,
XULCOMMANDDISPATCHER_ACTIVE = -5
XULCOMMANDDISPATCHER_FOCUSEDWINDOW = -2
};
/***********************************************************************/
@ -107,42 +104,6 @@ GetXULCommandDispatcherProperty(JSContext *cx, JSObject *obj, jsval id, jsval *v
}
break;
}
case XULCOMMANDDISPATCHER_SUPPRESSFOCUS:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUS, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
rv = a->GetSuppressFocus(&prop);
if (NS_SUCCEEDED(rv)) {
*vp = BOOLEAN_TO_JSVAL(prop);
}
}
break;
}
case XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
rv = a->GetSuppressFocusScroll(&prop);
if (NS_SUCCEEDED(rv)) {
*vp = BOOLEAN_TO_JSVAL(prop);
}
}
break;
}
case XULCOMMANDDISPATCHER_ACTIVE:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_ACTIVE, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
rv = a->GetActive(&prop);
if (NS_SUCCEEDED(rv)) {
*vp = BOOLEAN_TO_JSVAL(prop);
}
}
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, obj, id, vp);
}
@ -210,51 +171,6 @@ SetXULCommandDispatcherProperty(JSContext *cx, JSObject *obj, jsval id, jsval *v
}
break;
}
case XULCOMMANDDISPATCHER_SUPPRESSFOCUS:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUS, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToBool(&prop, cx, *vp)) {
rv = NS_ERROR_DOM_NOT_BOOLEAN_ERR;
break;
}
rv = a->SetSuppressFocus(prop);
}
break;
}
case XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToBool(&prop, cx, *vp)) {
rv = NS_ERROR_DOM_NOT_BOOLEAN_ERR;
break;
}
rv = a->SetSuppressFocusScroll(prop);
}
break;
}
case XULCOMMANDDISPATCHER_ACTIVE:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_ACTIVE, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToBool(&prop, cx, *vp)) {
rv = NS_ERROR_DOM_NOT_BOOLEAN_ERR;
break;
}
rv = a->SetActive(prop);
}
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, obj, id, vp);
}
@ -276,9 +192,6 @@ static JSPropertySpec XULCommandDispatcherProperties[] =
{
{"focusedElement", XULCOMMANDDISPATCHER_FOCUSEDELEMENT, JSPROP_ENUMERATE},
{"focusedWindow", XULCOMMANDDISPATCHER_FOCUSEDWINDOW, JSPROP_ENUMERATE},
{"suppressFocus", XULCOMMANDDISPATCHER_SUPPRESSFOCUS, JSPROP_ENUMERATE},
{"suppressFocusScroll", XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL, JSPROP_ENUMERATE},
{"active", XULCOMMANDDISPATCHER_ACTIVE, JSPROP_ENUMERATE},
{0}
};

Просмотреть файл

@ -30,6 +30,7 @@
#include "prprf.h"
#include "nsIComponentManager.h"
#include "nsIFocusController.h"
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptGlobalObjectOwner.h"
@ -635,13 +636,13 @@ nsEditorShell::PrepareDocumentForEditing(nsIDocumentLoader* aLoader, nsIURI *aUr
if (privContent)
{
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
privContent->GetRootCommandDispatcher(getter_AddRefs(commandDispatcher));
nsCOMPtr<nsIFocusController> focusController;
privContent->GetRootFocusController(getter_AddRefs(focusController));
if (commandDispatcher)
if (focusController)
{
nsCOMPtr<nsIDOMWindowInternal> focussedWindow;
commandDispatcher->GetFocusedWindow(getter_AddRefs(focussedWindow));
focusController->GetFocusedWindow(getter_AddRefs(focussedWindow));
if (focussedWindow.get() == contentInternal.get()) // now see if we are focussed
{

Просмотреть файл

@ -30,6 +30,7 @@
#include "prprf.h"
#include "nsIComponentManager.h"
#include "nsIFocusController.h"
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptGlobalObjectOwner.h"
@ -635,13 +636,13 @@ nsEditorShell::PrepareDocumentForEditing(nsIDocumentLoader* aLoader, nsIURI *aUr
if (privContent)
{
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
privContent->GetRootCommandDispatcher(getter_AddRefs(commandDispatcher));
nsCOMPtr<nsIFocusController> focusController;
privContent->GetRootFocusController(getter_AddRefs(focusController));
if (commandDispatcher)
if (focusController)
{
nsCOMPtr<nsIDOMWindowInternal> focussedWindow;
commandDispatcher->GetFocusedWindow(getter_AddRefs(focussedWindow));
focusController->GetFocusedWindow(getter_AddRefs(focussedWindow));
if (focussedWindow.get() == contentInternal.get()) // now see if we are focussed
{

Просмотреть файл

@ -111,10 +111,7 @@
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindowInternal.h"
#include "nsPIDOMWindow.h"
#ifdef INCLUDE_XUL
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULCommandDispatcher.h"
#endif // INCLUDE_XUL
#include "nsIFocusController.h"
// Drag & Drop, Clipboard
#include "nsWidgetsCID.h"
@ -2111,68 +2108,52 @@ PresShell::EndObservingDocument()
char* nsPresShell_ReflowStackPointerTop;
#endif
#ifdef INCLUDE_XUL
static void CheckForFocus(nsIDocument* aDocument)
{
// Now that we have a root frame, set focus in to the presshell, but
// only do this if our window is currently focused
// Restore focus if we're the active window or a parent of a previously
// active window.
// XXX The XUL dependency will go away when the focus tracking portion
// of the command dispatcher moves into the embedding layer.
nsCOMPtr<nsIScriptGlobalObject> globalObject;
aDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(globalObject);
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
NS_ASSERTION(rootWindow , "cannot get rootWindow");
if(nsnull == rootWindow)
return;
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIFocusController> focusController;
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
// Suppress the command dispatcher.
commandDispatcher->SetSuppressFocus(PR_TRUE);
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
commandDispatcher->GetFocusedWindow(getter_AddRefs(focusedWindow));
// See if the command dispatcher is holding on to an orphan window.
// This happens when you move from an inner frame to an outer frame
// (e.g., _parent, _top)
if (focusedWindow) {
nsCOMPtr<nsIDOMDocument> domDoc;
focusedWindow->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
// We're pointing to garbage. Go ahead and let this
// presshell take the focus.
focusedWindow = do_QueryInterface(ourWindow);
commandDispatcher->SetFocusedWindow(focusedWindow);
}
if (focusController) {
// Suppress the command dispatcher.
focusController->SetSuppressFocus(PR_TRUE);
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
// See if the command dispatcher is holding on to an orphan window.
// This happens when you move from an inner frame to an outer frame
// (e.g., _parent, _top)
if (focusedWindow) {
nsCOMPtr<nsIDOMDocument> domDoc;
focusedWindow->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
// We're pointing to garbage. Go ahead and let this
// presshell take the focus.
focusedWindow = do_QueryInterface(ourWindow);
focusController->SetFocusedWindow(focusedWindow);
}
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(ourWindow);
if (domWindow == focusedWindow) {
PRBool active;
commandDispatcher->GetActive(&active);
commandDispatcher->SetFocusedElement(nsnull);
if(active) {
// We need to restore focus and make sure we null
// out the focused element.
domWindow->Focus();
}
}
commandDispatcher->SetSuppressFocus(PR_FALSE);
}
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(ourWindow);
if (domWindow == focusedWindow) {
PRBool active;
focusController->GetActive(&active);
focusController->SetFocusedElement(nsnull);
if(active) {
// We need to restore focus and make sure we null
// out the focused element.
domWindow->Focus();
}
}
focusController->SetSuppressFocus(PR_FALSE);
}
}
#endif
nsresult
PresShell::NotifyReflowObservers(const char *aData)
@ -2294,9 +2275,7 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
mFrameManager->SetRootFrame(rootFrame);
}
#ifdef INCLUDE_XUL
CheckForFocus(mDocument);
#endif
// Have the style sheet processor construct frame for the root
// content object down
@ -2516,8 +2495,7 @@ NS_IMETHODIMP
PresShell::ScrollFrameIntoView(nsIFrame *aFrame){
if (!aFrame)
return NS_ERROR_NULL_POINTER;
#ifdef INCLUDE_XUL
// Before we scroll the frame into view, ask the command dispatcher
// if we're resetting focus because a window just got an activate
// event. If we are, we do not want to scroll the frame into view.
@ -2525,40 +2503,28 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame){
// window. When they reactivate the window, the expected behavior
// is not for the anchor link to scroll back into view. That is what
// this check is preventing.
// XXX: The dependency on the command dispatcher needs to be fixed.
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
if(content) {
nsCOMPtr<nsIDocument> document;
content->GetDocument(*getter_AddRefs(document));
if(document){
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
if(ourWindow) {
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
if(rootWindow) {
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
PRBool dontScroll;
commandDispatcher->GetSuppressFocusScroll(&dontScroll);
if(dontScroll)
return NS_OK;
}
}
}
}
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
PRBool dontScroll;
focusController->GetSuppressFocusScroll(&dontScroll);
if(dontScroll)
return NS_OK;
}
}
}
}
#endif
if (IsScrollingEnabled())
return ScrollFrameIntoView(aFrame, NS_PRESSHELL_SCROLL_ANYWHERE,
NS_PRESSHELL_SCROLL_ANYWHERE);
@ -3406,7 +3372,7 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
if (!aFrame) {
return NS_ERROR_NULL_POINTER;
}
#ifdef INCLUDE_XUL
// Before we scroll the frame into view, ask the command dispatcher
// if we're resetting focus because a window just got an activate
// event. If we are, we do not want to scroll the frame into view.
@ -3421,33 +3387,22 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
nsCOMPtr<nsIDocument> document;
content->GetDocument(*getter_AddRefs(document));
if(document){
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
if(ourWindow) {
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
if(rootWindow) {
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
PRBool dontScroll;
commandDispatcher->GetSuppressFocusScroll(&dontScroll);
if(dontScroll)
return NS_OK;
}
}
}
}
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
PRBool dontScroll;
focusController->GetSuppressFocusScroll(&dontScroll);
if(dontScroll)
return NS_OK;
}
}
}
}
#endif
if (mViewManager) {
// Get the viewport scroller
nsIScrollableView* scrollingView;

Просмотреть файл

@ -62,9 +62,11 @@
#include "nsIServiceManager.h"
#include "nsIPref.h"
#include "nsIChromeEventHandler.h"
#include "nsIFocusController.h"
#include "nsXULAtoms.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIObserverService.h"
#include "nsIDocShell.h"
#include "nsIMarkupDocumentViewer.h"
@ -333,16 +335,16 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
blurevent.message = NS_BLUR_CONTENT;
if(gLastFocusedPresContext) {
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
if(ourWindow) {
ourWindow->GetRootCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher)
commandDispatcher->SetSuppressFocus(PR_TRUE);
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController)
focusController->SetSuppressFocus(PR_TRUE);
}
gLastFocusedDocument->HandleDOMEvent(gLastFocusedPresContext, &blurevent, nsnull, NS_EVENT_FLAG_INIT, &blurstatus);
@ -350,8 +352,8 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
gLastFocusedContent->HandleDOMEvent(gLastFocusedPresContext, &blurevent, nsnull, NS_EVENT_FLAG_INIT, &blurstatus);
if (commandDispatcher) {
commandDispatcher->SetSuppressFocus(PR_FALSE);
if (focusController) {
focusController->SetSuppressFocus(PR_FALSE);
}
}
}
@ -399,56 +401,30 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
// objects.
EnsureDocument(aPresContext);
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIDOMElement> focusedElement;
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(mDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
// Obtain focus info from the command dispatcher.
commandDispatcher->GetFocusedWindow(getter_AddRefs(focusedWindow));
commandDispatcher->GetFocusedElement(getter_AddRefs(focusedElement));
commandDispatcher->SetSuppressFocusScroll(PR_TRUE);
}
nsCOMPtr<nsIScriptGlobalObject> globalObj;
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObj));
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(globalObj));
win->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
// Obtain focus info from the command dispatcher.
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
focusController->GetFocusedElement(getter_AddRefs(focusedElement));
focusController->SetSuppressFocusScroll(PR_TRUE);
}
if (!focusedWindow) {
nsCOMPtr<nsIScriptGlobalObject> globalObject;
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
focusedWindow = do_QueryInterface(globalObject);
nsCOMPtr<nsIScriptGlobalObject> globalObject;
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
focusedWindow = do_QueryInterface(globalObject);
}
// Sill no focused XULDocument, that is bad
if(!xulDoc && focusedWindow)
{
nsCOMPtr<nsPIDOMWindow> privateWindow = do_QueryInterface(focusedWindow);
if(privateWindow){
nsCOMPtr<nsIDOMWindowInternal> privateRootWindow;
privateWindow->GetPrivateRoot(getter_AddRefs(privateRootWindow));
if(privateRootWindow) {
nsCOMPtr<nsIDOMDocument> privateParentDoc;
privateRootWindow->GetDocument(getter_AddRefs(privateParentDoc));
xulDoc = do_QueryInterface(privateParentDoc);
}
}
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
// Obtain focus info from the command dispatcher.
commandDispatcher->GetFocusedWindow(getter_AddRefs(focusedWindow));
commandDispatcher->GetFocusedElement(getter_AddRefs(focusedElement));
commandDispatcher->SetSuppressFocusScroll(PR_TRUE);
}
}
}
// Focus the DOM window.
NS_WARN_IF_FALSE(focusedWindow,"check why focusedWindow is null!!!");
if(focusedWindow) {
@ -470,16 +446,16 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
}
}
if (commandDispatcher) {
commandDispatcher->SetActive(PR_TRUE);
if (focusController) {
focusController->SetActive(PR_TRUE);
PRBool isSuppressed;
commandDispatcher->GetSuppressFocus(&isSuppressed);
focusController->GetSuppressFocus(&isSuppressed);
while(isSuppressed){
commandDispatcher->SetSuppressFocus(PR_FALSE); // Unsuppress and let the command dispatcher listen again.
commandDispatcher->GetSuppressFocus(&isSuppressed);
focusController->SetSuppressFocus(PR_FALSE); // Unsuppress and let the command dispatcher listen again.
focusController->GetSuppressFocus(&isSuppressed);
}
commandDispatcher->SetSuppressFocusScroll(PR_FALSE);
focusController->SetSuppressFocusScroll(PR_FALSE);
}
}
break;
@ -508,24 +484,14 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
// de-activation. This will cause it to remember the last
// focused sub-window and sub-element for this top-level
// window.
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
if(ourWindow) {
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
if(rootWindow) {
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
// Suppress the command dispatcher.
commandDispatcher->SetSuppressFocus(PR_TRUE);
}
}
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
// Suppress the command dispatcher.
focusController->SetSuppressFocus(PR_TRUE);
}
}
@ -577,9 +543,9 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
gLastFocusedPresContext = nsnull;
}
if (commandDispatcher) {
commandDispatcher->SetActive(PR_FALSE);
//commandDispatcher->SetSuppressFocus(PR_FALSE);
if (focusController) {
focusController->SetActive(PR_FALSE);
//focusController->SetSuppressFocus(PR_FALSE);
}
}
@ -955,7 +921,6 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
PRInt32 action = 0;
PRInt32 numLines = 0;
PRBool aBool;
if (msEvent->isShift) {
mPrefService->GetIntPref("mousewheel.withshiftkey.action", &action);
mPrefService->GetBoolPref("mousewheel.withshiftkey.sysnumlines",
@ -2687,8 +2652,8 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// Make sure we're not switching command dispatchers, if so, surpress the blurred one
if(gLastFocusedDocument && mDocument) {
nsCOMPtr<nsIDOMXULCommandDispatcher> newCommandDispatcher;
nsCOMPtr<nsIDOMXULCommandDispatcher> oldCommandDispatcher;
nsCOMPtr<nsIFocusController> newFocusController;
nsCOMPtr<nsIFocusController> oldFocusController;
nsCOMPtr<nsPIDOMWindow> oldPIDOMWindow;
nsCOMPtr<nsPIDOMWindow> newPIDOMWindow;
nsCOMPtr<nsIScriptGlobalObject> oldGlobal;
@ -2698,11 +2663,11 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(newGlobal);
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(oldGlobal);
if(newWindow)
newWindow->GetRootCommandDispatcher(getter_AddRefs(newCommandDispatcher));
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
if(oldWindow)
oldWindow->GetRootCommandDispatcher(getter_AddRefs(oldCommandDispatcher));
if(oldCommandDispatcher && oldCommandDispatcher != newCommandDispatcher)
oldCommandDispatcher->SetSuppressFocus(PR_TRUE);
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
if(oldFocusController && oldFocusController != newFocusController)
oldFocusController->SetSuppressFocus(PR_TRUE);
}
nsCOMPtr<nsIEventStateManager> esm;
@ -2737,8 +2702,8 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// Make sure we're not switching command dispatchers, if so, surpress the blurred one
if(mDocument) {
nsCOMPtr<nsIDOMXULCommandDispatcher> newCommandDispatcher;
nsCOMPtr<nsIDOMXULCommandDispatcher> oldCommandDispatcher;
nsCOMPtr<nsIFocusController> newFocusController;
nsCOMPtr<nsIFocusController> oldFocusController;
nsCOMPtr<nsPIDOMWindow> oldPIDOMWindow;
nsCOMPtr<nsPIDOMWindow> newPIDOMWindow;
nsCOMPtr<nsIScriptGlobalObject> oldGlobal;
@ -2748,10 +2713,10 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(newGlobal);
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(oldGlobal);
newWindow->GetRootCommandDispatcher(getter_AddRefs(newCommandDispatcher));
oldWindow->GetRootCommandDispatcher(getter_AddRefs(oldCommandDispatcher));
if(oldCommandDispatcher && oldCommandDispatcher != newCommandDispatcher)
oldCommandDispatcher->SetSuppressFocus(PR_TRUE);
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
if(oldFocusController && oldFocusController != newFocusController)
oldFocusController->SetSuppressFocus(PR_TRUE);
}
nsCOMPtr<nsIEventStateManager> esm;
@ -2963,6 +2928,12 @@ nsEventStateManager::DispatchNewEvent(nsISupports* aTarget, nsIDOMEvent* aEvent)
if (target) {
ret = target->HandleDOMEvent(mPresContext, innerEvent, &aEvent, NS_EVENT_FLAG_INIT, &status);
}
else {
nsCOMPtr<nsIChromeEventHandler> target(do_QueryInterface(aTarget));
if (target) {
ret = target->HandleChromeEvent(mPresContext, innerEvent, &aEvent, NS_EVENT_FLAG_INIT, &status);
}
}
}
}
}

Просмотреть файл

@ -111,10 +111,7 @@
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindowInternal.h"
#include "nsPIDOMWindow.h"
#ifdef INCLUDE_XUL
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULCommandDispatcher.h"
#endif // INCLUDE_XUL
#include "nsIFocusController.h"
// Drag & Drop, Clipboard
#include "nsWidgetsCID.h"
@ -2111,68 +2108,52 @@ PresShell::EndObservingDocument()
char* nsPresShell_ReflowStackPointerTop;
#endif
#ifdef INCLUDE_XUL
static void CheckForFocus(nsIDocument* aDocument)
{
// Now that we have a root frame, set focus in to the presshell, but
// only do this if our window is currently focused
// Restore focus if we're the active window or a parent of a previously
// active window.
// XXX The XUL dependency will go away when the focus tracking portion
// of the command dispatcher moves into the embedding layer.
nsCOMPtr<nsIScriptGlobalObject> globalObject;
aDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(globalObject);
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
NS_ASSERTION(rootWindow , "cannot get rootWindow");
if(nsnull == rootWindow)
return;
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIFocusController> focusController;
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
// Suppress the command dispatcher.
commandDispatcher->SetSuppressFocus(PR_TRUE);
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
commandDispatcher->GetFocusedWindow(getter_AddRefs(focusedWindow));
// See if the command dispatcher is holding on to an orphan window.
// This happens when you move from an inner frame to an outer frame
// (e.g., _parent, _top)
if (focusedWindow) {
nsCOMPtr<nsIDOMDocument> domDoc;
focusedWindow->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
// We're pointing to garbage. Go ahead and let this
// presshell take the focus.
focusedWindow = do_QueryInterface(ourWindow);
commandDispatcher->SetFocusedWindow(focusedWindow);
}
if (focusController) {
// Suppress the command dispatcher.
focusController->SetSuppressFocus(PR_TRUE);
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
// See if the command dispatcher is holding on to an orphan window.
// This happens when you move from an inner frame to an outer frame
// (e.g., _parent, _top)
if (focusedWindow) {
nsCOMPtr<nsIDOMDocument> domDoc;
focusedWindow->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
// We're pointing to garbage. Go ahead and let this
// presshell take the focus.
focusedWindow = do_QueryInterface(ourWindow);
focusController->SetFocusedWindow(focusedWindow);
}
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(ourWindow);
if (domWindow == focusedWindow) {
PRBool active;
commandDispatcher->GetActive(&active);
commandDispatcher->SetFocusedElement(nsnull);
if(active) {
// We need to restore focus and make sure we null
// out the focused element.
domWindow->Focus();
}
}
commandDispatcher->SetSuppressFocus(PR_FALSE);
}
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(ourWindow);
if (domWindow == focusedWindow) {
PRBool active;
focusController->GetActive(&active);
focusController->SetFocusedElement(nsnull);
if(active) {
// We need to restore focus and make sure we null
// out the focused element.
domWindow->Focus();
}
}
focusController->SetSuppressFocus(PR_FALSE);
}
}
#endif
nsresult
PresShell::NotifyReflowObservers(const char *aData)
@ -2294,9 +2275,7 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
mFrameManager->SetRootFrame(rootFrame);
}
#ifdef INCLUDE_XUL
CheckForFocus(mDocument);
#endif
// Have the style sheet processor construct frame for the root
// content object down
@ -2516,8 +2495,7 @@ NS_IMETHODIMP
PresShell::ScrollFrameIntoView(nsIFrame *aFrame){
if (!aFrame)
return NS_ERROR_NULL_POINTER;
#ifdef INCLUDE_XUL
// Before we scroll the frame into view, ask the command dispatcher
// if we're resetting focus because a window just got an activate
// event. If we are, we do not want to scroll the frame into view.
@ -2525,40 +2503,28 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame){
// window. When they reactivate the window, the expected behavior
// is not for the anchor link to scroll back into view. That is what
// this check is preventing.
// XXX: The dependency on the command dispatcher needs to be fixed.
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
if(content) {
nsCOMPtr<nsIDocument> document;
content->GetDocument(*getter_AddRefs(document));
if(document){
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
if(ourWindow) {
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
if(rootWindow) {
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
PRBool dontScroll;
commandDispatcher->GetSuppressFocusScroll(&dontScroll);
if(dontScroll)
return NS_OK;
}
}
}
}
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
PRBool dontScroll;
focusController->GetSuppressFocusScroll(&dontScroll);
if(dontScroll)
return NS_OK;
}
}
}
}
#endif
if (IsScrollingEnabled())
return ScrollFrameIntoView(aFrame, NS_PRESSHELL_SCROLL_ANYWHERE,
NS_PRESSHELL_SCROLL_ANYWHERE);
@ -3406,7 +3372,7 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
if (!aFrame) {
return NS_ERROR_NULL_POINTER;
}
#ifdef INCLUDE_XUL
// Before we scroll the frame into view, ask the command dispatcher
// if we're resetting focus because a window just got an activate
// event. If we are, we do not want to scroll the frame into view.
@ -3421,33 +3387,22 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
nsCOMPtr<nsIDocument> document;
content->GetDocument(*getter_AddRefs(document));
if(document){
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
if(ourWindow) {
ourWindow->GetPrivateRoot(getter_AddRefs(rootWindow));
if(rootWindow) {
nsCOMPtr<nsIDOMDocument> rootDocument;
rootWindow->GetDocument(getter_AddRefs(rootDocument));
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(rootDocument);
if (xulDoc) {
// See if we have a command dispatcher attached.
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
PRBool dontScroll;
commandDispatcher->GetSuppressFocusScroll(&dontScroll);
if(dontScroll)
return NS_OK;
}
}
}
}
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) {
PRBool dontScroll;
focusController->GetSuppressFocusScroll(&dontScroll);
if(dontScroll)
return NS_OK;
}
}
}
}
#endif
if (mViewManager) {
// Get the viewport scroller
nsIScrollableView* scrollingView;

Просмотреть файл

@ -42,12 +42,13 @@
#include "nsIDOMNSHTMLTextAreaElement.h"
#include "nsIDOMNSHTMLInputElement.h"
#include "nsIDOMText.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIFocusController.h"
#include "nsIEventListenerManager.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMEventListener.h"
#include "nsIPrivateDOMEvent.h"
#include "nsPIDOMWindow.h"
#include "nsPIWindowRoot.h"
#include "nsIDOMWindowInternal.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
@ -218,29 +219,36 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven
// Instead of executing JS, let's get the controller for the bound
// element and call doCommand on it.
nsCOMPtr<nsIController> controller;
nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsPIDOMWindow> privateWindow(do_QueryInterface(aReceiver));
if (!privateWindow) {
nsCOMPtr<nsIContent> elt(do_QueryInterface(aReceiver));
nsCOMPtr<nsIDocument> doc;
if (elt)
elt->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsPIWindowRoot> windowRoot(do_QueryInterface(aReceiver));
if (windowRoot) {
windowRoot->GetFocusController(getter_AddRefs(focusController));
}
else {
nsCOMPtr<nsPIDOMWindow> privateWindow(do_QueryInterface(aReceiver));
if (!privateWindow) {
nsCOMPtr<nsIContent> elt(do_QueryInterface(aReceiver));
nsCOMPtr<nsIDocument> doc;
if (elt)
elt->GetDocument(*getter_AddRefs(doc));
if (!doc)
doc = do_QueryInterface(aReceiver);
if (!doc)
doc = do_QueryInterface(aReceiver);
if (!doc)
return NS_ERROR_FAILURE;
if (!doc)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIScriptGlobalObject> globalObject;
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
privateWindow = do_QueryInterface(globalObject);
nsCOMPtr<nsIScriptGlobalObject> globalObject;
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
privateWindow = do_QueryInterface(globalObject);
}
privateWindow->GetRootFocusController(getter_AddRefs(focusController));
}
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
privateWindow->GetRootCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher)
commandDispatcher->GetControllerForCommand(command, getter_AddRefs(controller));
if (focusController)
focusController->GetControllerForCommand(command, getter_AddRefs(controller));
else GetController(aReceiver, getter_AddRefs(controller)); // We're attached to the receiver possibly.
if (controller)
@ -271,12 +279,25 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven
mHandlerElement->GetAttribute(kNameSpaceID_None, kOnCommandAtom, handlerText);
if (handlerText.IsEmpty())
return NS_ERROR_FAILURE; // For whatever reason, they didn't give us anything to do.
aEvent->PreventDefault(); // Preventing default for XUL key handlers
aEvent->PreventDefault(); // Preventing default for XUL key handlers
}
}
// Compile the handler and bind it to the element.
nsCOMPtr<nsIScriptGlobalObject> boundGlobal(do_QueryInterface(aReceiver));
nsCOMPtr<nsIScriptGlobalObject> boundGlobal;
nsCOMPtr<nsPIWindowRoot> winRoot(do_QueryInterface(aReceiver));
if (winRoot) {
nsCOMPtr<nsIFocusController> focusController;
winRoot->GetFocusController(getter_AddRefs(focusController));
nsCOMPtr<nsIDOMWindowInternal> win;
focusController->GetFocusedWindow(getter_AddRefs(win));
nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(win));
nsCOMPtr<nsIDOMWindowInternal> rootWin;
piWin->GetPrivateRoot(getter_AddRefs(rootWin));
boundGlobal = do_QueryInterface(rootWin);
}
else boundGlobal = do_QueryInterface(aReceiver);
if (!boundGlobal) {
nsCOMPtr<nsIDocument> boundDocument(do_QueryInterface(aReceiver));
if (!boundDocument) {
@ -293,7 +314,8 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven
nsCOMPtr<nsIScriptContext> boundContext;
boundGlobal->GetContext(getter_AddRefs(boundContext));
nsCOMPtr<nsIScriptObjectOwner> owner(do_QueryInterface(aReceiver));
nsCOMPtr<nsIScriptObjectOwner> owner(do_QueryInterface(winRoot ? boundGlobal : aReceiver));
void* scriptObject;
owner->GetScriptObject(boundContext, &scriptObject);

Просмотреть файл

@ -39,12 +39,13 @@
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindowInternal.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIFocusController.h"
#include "nsIDocShell.h"
#include "nsIPresShell.h"
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsIDOMElement.h"
#include "nsPIWindowRoot.h"
PRUint32 nsXBLWindowKeyHandler::gRefCnt = 0;
nsIAtom* nsXBLWindowKeyHandler::kKeyDownAtom = nsnull;
@ -90,16 +91,16 @@ NS_IMPL_ISUPPORTS1(nsXBLWindowKeyHandler, nsIDOMKeyListener)
PRBool
nsXBLWindowKeyHandler::IsEditor()
{
nsCOMPtr<nsPIDOMWindow> privateWindow(do_QueryInterface(mReceiver));
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
privateWindow->GetRootCommandDispatcher(getter_AddRefs(commandDispatcher));
if (!commandDispatcher) {
NS_WARNING("********* Problem for embedding. They have no command dispatcher!!!\n");
nsCOMPtr<nsPIWindowRoot> windowRoot(do_QueryInterface(mReceiver));
nsCOMPtr<nsIFocusController> focusController;
windowRoot->GetFocusController(getter_AddRefs(focusController));
if (!focusController) {
NS_WARNING("********* Something went wrong! No focus controller on the root!!!\n");
return PR_FALSE;
}
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
commandDispatcher->GetFocusedWindow(getter_AddRefs(focusedWindow));
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
if (!focusedWindow)
return PR_FALSE;

Просмотреть файл

@ -5,9 +5,6 @@ interface XULCommandDispatcher {
attribute Element focusedElement;
attribute WindowInternal focusedWindow;
attribute boolean suppressFocus;
attribute boolean suppressFocusScroll;
attribute boolean active;
void addCommandUpdater(in Element updater, in DOMString events, in DOMString targets);
void removeCommandUpdater(in Element updater);
@ -15,6 +12,5 @@ interface XULCommandDispatcher {
void updateCommands(in DOMString eventName);
xpidl nsIController getControllerForCommand(in DOMString command);
xpidl nsIControllers getControllers();
};

Просмотреть файл

@ -47,15 +47,6 @@ public:
NS_IMETHOD GetFocusedWindow(nsIDOMWindowInternal** aFocusedWindow)=0;
NS_IMETHOD SetFocusedWindow(nsIDOMWindowInternal* aFocusedWindow)=0;
NS_IMETHOD GetSuppressFocus(PRBool* aSuppressFocus)=0;
NS_IMETHOD SetSuppressFocus(PRBool aSuppressFocus)=0;
NS_IMETHOD GetSuppressFocusScroll(PRBool* aSuppressFocusScroll)=0;
NS_IMETHOD SetSuppressFocusScroll(PRBool aSuppressFocusScroll)=0;
NS_IMETHOD GetActive(PRBool* aActive)=0;
NS_IMETHOD SetActive(PRBool aActive)=0;
NS_IMETHOD AddCommandUpdater(nsIDOMElement* aUpdater, const nsAReadableString& aEvents, const nsAReadableString& aTargets)=0;
NS_IMETHOD RemoveCommandUpdater(nsIDOMElement* aUpdater)=0;
@ -73,12 +64,6 @@ public:
NS_IMETHOD SetFocusedElement(nsIDOMElement* aFocusedElement); \
NS_IMETHOD GetFocusedWindow(nsIDOMWindowInternal** aFocusedWindow); \
NS_IMETHOD SetFocusedWindow(nsIDOMWindowInternal* aFocusedWindow); \
NS_IMETHOD GetSuppressFocus(PRBool* aSuppressFocus); \
NS_IMETHOD SetSuppressFocus(PRBool aSuppressFocus); \
NS_IMETHOD GetSuppressFocusScroll(PRBool* aSuppressFocusScroll); \
NS_IMETHOD SetSuppressFocusScroll(PRBool aSuppressFocusScroll); \
NS_IMETHOD GetActive(PRBool* aActive); \
NS_IMETHOD SetActive(PRBool aActive); \
NS_IMETHOD AddCommandUpdater(nsIDOMElement* aUpdater, const nsAReadableString& aEvents, const nsAReadableString& aTargets); \
NS_IMETHOD RemoveCommandUpdater(nsIDOMElement* aUpdater); \
NS_IMETHOD UpdateCommands(const nsAReadableString& aEventName); \
@ -92,12 +77,6 @@ public:
NS_IMETHOD SetFocusedElement(nsIDOMElement* aFocusedElement) { return _to SetFocusedElement(aFocusedElement); } \
NS_IMETHOD GetFocusedWindow(nsIDOMWindowInternal** aFocusedWindow) { return _to GetFocusedWindow(aFocusedWindow); } \
NS_IMETHOD SetFocusedWindow(nsIDOMWindowInternal* aFocusedWindow) { return _to SetFocusedWindow(aFocusedWindow); } \
NS_IMETHOD GetSuppressFocus(PRBool* aSuppressFocus) { return _to GetSuppressFocus(aSuppressFocus); } \
NS_IMETHOD SetSuppressFocus(PRBool aSuppressFocus) { return _to SetSuppressFocus(aSuppressFocus); } \
NS_IMETHOD GetSuppressFocusScroll(PRBool* aSuppressFocusScroll) { return _to GetSuppressFocusScroll(aSuppressFocusScroll); } \
NS_IMETHOD SetSuppressFocusScroll(PRBool aSuppressFocusScroll) { return _to SetSuppressFocusScroll(aSuppressFocusScroll); } \
NS_IMETHOD GetActive(PRBool* aActive) { return _to GetActive(aActive); } \
NS_IMETHOD SetActive(PRBool aActive) { return _to SetActive(aActive); } \
NS_IMETHOD AddCommandUpdater(nsIDOMElement* aUpdater, const nsAReadableString& aEvents, const nsAReadableString& aTargets) { return _to AddCommandUpdater(aUpdater, aEvents, aTargets); } \
NS_IMETHOD RemoveCommandUpdater(nsIDOMElement* aUpdater) { return _to RemoveCommandUpdater(aUpdater); } \
NS_IMETHOD UpdateCommands(const nsAReadableString& aEventName) { return _to UpdateCommands(aEventName); } \

Просмотреть файл

@ -1,674 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* AUTO-GENERATED. DO NOT EDIT!!! */
#include "jsapi.h"
#include "nsJSUtils.h"
#include "nsDOMError.h"
#include "nscore.h"
#include "nsIServiceManager.h"
#include "nsIScriptContext.h"
#include "nsIScriptSecurityManager.h"
#include "nsIJSScriptObject.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsCOMPtr.h"
#include "nsDOMPropEnums.h"
#include "nsString.h"
#include "nsIController.h"
#include "nsIDOMElement.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIControllers.h"
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kIControllerIID, NS_ICONTROLLER_IID);
static NS_DEFINE_IID(kIElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIWindowInternalIID, NS_IDOMWINDOWINTERNAL_IID);
static NS_DEFINE_IID(kIXULCommandDispatcherIID, NS_IDOMXULCOMMANDDISPATCHER_IID);
static NS_DEFINE_IID(kIControllersIID, NS_ICONTROLLERS_IID);
//
// XULCommandDispatcher property ids
//
enum XULCommandDispatcher_slots {
XULCOMMANDDISPATCHER_FOCUSEDELEMENT = -1,
XULCOMMANDDISPATCHER_FOCUSEDWINDOW = -2,
XULCOMMANDDISPATCHER_SUPPRESSFOCUS = -3,
XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL = -4,
XULCOMMANDDISPATCHER_ACTIVE = -5
};
/***********************************************************************/
//
// XULCommandDispatcher Properties Getter
//
PR_STATIC_CALLBACK(JSBool)
GetXULCommandDispatcherProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULCommandDispatcher *a = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
nsresult rv = NS_OK;
if (JSVAL_IS_INT(id)) {
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
switch(JSVAL_TO_INT(id)) {
case XULCOMMANDDISPATCHER_FOCUSEDELEMENT:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_FOCUSEDELEMENT, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
nsIDOMElement* prop;
rv = a->GetFocusedElement(&prop);
if (NS_SUCCEEDED(rv)) {
// get the js object
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, obj, vp);
}
}
break;
}
case XULCOMMANDDISPATCHER_FOCUSEDWINDOW:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_FOCUSEDWINDOW, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
nsIDOMWindowInternal* prop;
rv = a->GetFocusedWindow(&prop);
if (NS_SUCCEEDED(rv)) {
// get the js object
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, obj, vp);
}
}
break;
}
case XULCOMMANDDISPATCHER_SUPPRESSFOCUS:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUS, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
rv = a->GetSuppressFocus(&prop);
if (NS_SUCCEEDED(rv)) {
*vp = BOOLEAN_TO_JSVAL(prop);
}
}
break;
}
case XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
rv = a->GetSuppressFocusScroll(&prop);
if (NS_SUCCEEDED(rv)) {
*vp = BOOLEAN_TO_JSVAL(prop);
}
}
break;
}
case XULCOMMANDDISPATCHER_ACTIVE:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_ACTIVE, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
rv = a->GetActive(&prop);
if (NS_SUCCEEDED(rv)) {
*vp = BOOLEAN_TO_JSVAL(prop);
}
}
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, obj, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, obj, id, vp);
}
if (NS_FAILED(rv))
return nsJSUtils::nsReportError(cx, obj, rv);
return PR_TRUE;
}
/***********************************************************************/
//
// XULCommandDispatcher Properties Setter
//
PR_STATIC_CALLBACK(JSBool)
SetXULCommandDispatcherProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULCommandDispatcher *a = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
nsresult rv = NS_OK;
if (JSVAL_IS_INT(id)) {
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
switch(JSVAL_TO_INT(id)) {
case XULCOMMANDDISPATCHER_FOCUSEDELEMENT:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_FOCUSEDELEMENT, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
nsIDOMElement* prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&prop,
kIElementIID, NS_ConvertASCIItoUCS2("Element"),
cx, *vp)) {
rv = NS_ERROR_DOM_NOT_OBJECT_ERR;
break;
}
rv = a->SetFocusedElement(prop);
NS_IF_RELEASE(prop);
}
break;
}
case XULCOMMANDDISPATCHER_FOCUSEDWINDOW:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_FOCUSEDWINDOW, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
nsIDOMWindowInternal* prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&prop,
kIWindowInternalIID, NS_ConvertASCIItoUCS2("WindowInternal"),
cx, *vp)) {
rv = NS_ERROR_DOM_NOT_OBJECT_ERR;
break;
}
rv = a->SetFocusedWindow(prop);
NS_IF_RELEASE(prop);
}
break;
}
case XULCOMMANDDISPATCHER_SUPPRESSFOCUS:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUS, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToBool(&prop, cx, *vp)) {
rv = NS_ERROR_DOM_NOT_BOOLEAN_ERR;
break;
}
rv = a->SetSuppressFocus(prop);
}
break;
}
case XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToBool(&prop, cx, *vp)) {
rv = NS_ERROR_DOM_NOT_BOOLEAN_ERR;
break;
}
rv = a->SetSuppressFocusScroll(prop);
}
break;
}
case XULCOMMANDDISPATCHER_ACTIVE:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_ACTIVE, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
PRBool prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToBool(&prop, cx, *vp)) {
rv = NS_ERROR_DOM_NOT_BOOLEAN_ERR;
break;
}
rv = a->SetActive(prop);
}
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, obj, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, obj, id, vp);
}
if (NS_FAILED(rv))
return nsJSUtils::nsReportError(cx, obj, rv);
return PR_TRUE;
}
//
// XULCommandDispatcher class properties
//
static JSPropertySpec XULCommandDispatcherProperties[] =
{
{"focusedElement", XULCOMMANDDISPATCHER_FOCUSEDELEMENT, JSPROP_ENUMERATE},
{"focusedWindow", XULCOMMANDDISPATCHER_FOCUSEDWINDOW, JSPROP_ENUMERATE},
{"suppressFocus", XULCOMMANDDISPATCHER_SUPPRESSFOCUS, JSPROP_ENUMERATE},
{"suppressFocusScroll", XULCOMMANDDISPATCHER_SUPPRESSFOCUSSCROLL, JSPROP_ENUMERATE},
{"active", XULCOMMANDDISPATCHER_ACTIVE, JSPROP_ENUMERATE},
{0}
};
//
// XULCommandDispatcher finalizer
//
PR_STATIC_CALLBACK(void)
FinalizeXULCommandDispatcher(JSContext *cx, JSObject *obj)
{
nsJSUtils::nsGenericFinalize(cx, obj);
}
//
// XULCommandDispatcher enumerate
//
PR_STATIC_CALLBACK(JSBool)
EnumerateXULCommandDispatcher(JSContext *cx, JSObject *obj)
{
return nsJSUtils::nsGenericEnumerate(cx, obj, nsnull);
}
//
// XULCommandDispatcher resolve
//
PR_STATIC_CALLBACK(JSBool)
ResolveXULCommandDispatcher(JSContext *cx, JSObject *obj, jsval id)
{
return nsJSUtils::nsGenericResolve(cx, obj, id, nsnull);
}
//
// Native method AddCommandUpdater
//
PR_STATIC_CALLBACK(JSBool)
XULCommandDispatcherAddCommandUpdater(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULCommandDispatcher *nativeThis = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
nsCOMPtr<nsIDOMElement> b0;
nsAutoString b1;
nsAutoString b2;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_ADDCOMMANDUPDATER, PR_FALSE);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
if (argc < 3) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)(void**)getter_AddRefs(b0),
kIElementIID,
NS_ConvertASCIItoUCS2("Element"),
cx,
argv[0])) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_OBJECT_ERR);
}
nsJSUtils::nsConvertJSValToString(b1, cx, argv[1]);
nsJSUtils::nsConvertJSValToString(b2, cx, argv[2]);
result = nativeThis->AddCommandUpdater(b0, b1, b2);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
*rval = JSVAL_VOID;
}
return JS_TRUE;
}
//
// Native method RemoveCommandUpdater
//
PR_STATIC_CALLBACK(JSBool)
XULCommandDispatcherRemoveCommandUpdater(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULCommandDispatcher *nativeThis = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
nsCOMPtr<nsIDOMElement> b0;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_REMOVECOMMANDUPDATER, PR_FALSE);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
if (argc < 1) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)(void**)getter_AddRefs(b0),
kIElementIID,
NS_ConvertASCIItoUCS2("Element"),
cx,
argv[0])) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_OBJECT_ERR);
}
result = nativeThis->RemoveCommandUpdater(b0);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
*rval = JSVAL_VOID;
}
return JS_TRUE;
}
//
// Native method UpdateCommands
//
PR_STATIC_CALLBACK(JSBool)
XULCommandDispatcherUpdateCommands(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULCommandDispatcher *nativeThis = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
nsAutoString b0;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_UPDATECOMMANDS, PR_FALSE);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
if (argc < 1) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
result = nativeThis->UpdateCommands(b0);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
*rval = JSVAL_VOID;
}
return JS_TRUE;
}
//
// Native method GetControllerForCommand
//
PR_STATIC_CALLBACK(JSBool)
XULCommandDispatcherGetControllerForCommand(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULCommandDispatcher *nativeThis = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
nsIController* nativeRet;
nsAutoString b0;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_GETCONTROLLERFORCOMMAND, PR_FALSE);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
if (argc < 1) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
result = nativeThis->GetControllerForCommand(b0, &nativeRet);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
// n.b., this will release nativeRet
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, NS_GET_IID(nsIController), cx, obj, rval);
}
return JS_TRUE;
}
//
// Native method GetControllers
//
PR_STATIC_CALLBACK(JSBool)
XULCommandDispatcherGetControllers(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULCommandDispatcher *nativeThis = (nsIDOMXULCommandDispatcher*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
nsIControllers* nativeRet;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
nsIScriptSecurityManager *secMan = nsJSUtils::nsGetSecurityManager(cx, obj);
if (!secMan)
return PR_FALSE;
result = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULCOMMANDDISPATCHER_GETCONTROLLERS, PR_FALSE);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
result = nativeThis->GetControllers(&nativeRet);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
// n.b., this will release nativeRet
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, NS_GET_IID(nsIControllers), cx, obj, rval);
}
return JS_TRUE;
}
/***********************************************************************/
//
// class for XULCommandDispatcher
//
JSClass XULCommandDispatcherClass = {
"XULCommandDispatcher",
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS,
JS_PropertyStub,
JS_PropertyStub,
GetXULCommandDispatcherProperty,
SetXULCommandDispatcherProperty,
EnumerateXULCommandDispatcher,
ResolveXULCommandDispatcher,
JS_ConvertStub,
FinalizeXULCommandDispatcher,
nsnull,
nsJSUtils::nsCheckAccess
};
//
// XULCommandDispatcher class methods
//
static JSFunctionSpec XULCommandDispatcherMethods[] =
{
{"addCommandUpdater", XULCommandDispatcherAddCommandUpdater, 3},
{"removeCommandUpdater", XULCommandDispatcherRemoveCommandUpdater, 1},
{"updateCommands", XULCommandDispatcherUpdateCommands, 1},
{"getControllerForCommand", XULCommandDispatcherGetControllerForCommand, 1},
{"getControllers", XULCommandDispatcherGetControllers, 0},
{0}
};
//
// XULCommandDispatcher constructor
//
PR_STATIC_CALLBACK(JSBool)
XULCommandDispatcher(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
return JS_FALSE;
}
//
// XULCommandDispatcher class initialization
//
extern "C" NS_DOM nsresult NS_InitXULCommandDispatcherClass(nsIScriptContext *aContext, void **aPrototype)
{
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
JSObject *proto = nsnull;
JSObject *constructor = nsnull;
JSObject *parent_proto = nsnull;
JSObject *global = JS_GetGlobalObject(jscontext);
jsval vp;
if ((PR_TRUE != JS_LookupProperty(jscontext, global, "XULCommandDispatcher", &vp)) ||
!JSVAL_IS_OBJECT(vp) ||
((constructor = JSVAL_TO_OBJECT(vp)) == nsnull) ||
(PR_TRUE != JS_LookupProperty(jscontext, JSVAL_TO_OBJECT(vp), "prototype", &vp)) ||
!JSVAL_IS_OBJECT(vp)) {
proto = JS_InitClass(jscontext, // context
global, // global object
parent_proto, // parent proto
&XULCommandDispatcherClass, // JSClass
XULCommandDispatcher, // JSNative ctor
0, // ctor args
XULCommandDispatcherProperties, // proto props
XULCommandDispatcherMethods, // proto funcs
nsnull, // ctor props (static)
nsnull); // ctor funcs (static)
if (nsnull == proto) {
return NS_ERROR_FAILURE;
}
}
else if ((nsnull != constructor) && JSVAL_IS_OBJECT(vp)) {
proto = JSVAL_TO_OBJECT(vp);
}
else {
return NS_ERROR_FAILURE;
}
if (aPrototype) {
*aPrototype = proto;
}
return NS_OK;
}
//
// Method for creating a new XULCommandDispatcher JavaScript object
//
extern "C" NS_DOM nsresult NS_NewScriptXULCommandDispatcher(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
{
NS_PRECONDITION(nsnull != aContext && nsnull != aSupports && nsnull != aReturn, "null argument to NS_NewScriptXULCommandDispatcher");
JSObject *proto;
JSObject *parent;
nsIScriptObjectOwner *owner;
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
nsresult result = NS_OK;
nsIDOMXULCommandDispatcher *aXULCommandDispatcher;
if (nsnull == aParent) {
parent = nsnull;
}
else if (NS_OK == aParent->QueryInterface(kIScriptObjectOwnerIID, (void**)&owner)) {
if (NS_OK != owner->GetScriptObject(aContext, (void **)&parent)) {
NS_RELEASE(owner);
return NS_ERROR_FAILURE;
}
NS_RELEASE(owner);
}
else {
return NS_ERROR_FAILURE;
}
if (NS_OK != NS_InitXULCommandDispatcherClass(aContext, (void **)&proto)) {
return NS_ERROR_FAILURE;
}
result = aSupports->QueryInterface(kIXULCommandDispatcherIID, (void **)&aXULCommandDispatcher);
if (NS_OK != result) {
return result;
}
// create a js object for this class
*aReturn = JS_NewObject(jscontext, &XULCommandDispatcherClass, proto, parent);
if (nsnull != *aReturn) {
// connect the native object to the js object
JS_SetPrivate(jscontext, (JSObject *)*aReturn, aXULCommandDispatcher);
}
else {
NS_RELEASE(aXULCommandDispatcher);
return NS_ERROR_FAILURE;
}
return NS_OK;
}

Просмотреть файл

@ -1,665 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
* Contributor(s):
*/
/*
This file provides the implementation for the XUL Command Dispatcher.
*/
#include "nsIContent.h"
#include "nsIControllers.h"
#include "nsIDOMDocument.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMNSHTMLInputElement.h"
#include "nsIDOMNSHTMLTextAreaElement.h"
#include "nsIDOMUIEvent.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMXULElement.h"
#include "nsIDocument.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIScriptGlobalObject.h"
#include "nsPIDOMWindow.h"
#include "nsRDFCID.h"
#include "nsXULCommandDispatcher.h"
#include "prlog.h"
#include "nsIDOMEventTarget.h"
#ifdef PR_LOGGING
static PRLogModuleInfo* gLog;
#endif
////////////////////////////////////////////////////////////////////////
nsXULCommandDispatcher::nsXULCommandDispatcher(void)
: mScriptObject(nsnull), mSuppressFocus(0),
mActive(PR_FALSE), mFocusInitialized(PR_FALSE), mUpdaters(nsnull)
{
NS_INIT_REFCNT();
#ifdef PR_LOGGING
if (! gLog)
gLog = PR_NewLogModule("nsXULCommandDispatcher");
#endif
}
nsXULCommandDispatcher::~nsXULCommandDispatcher(void)
{
while (mUpdaters) {
Updater* doomed = mUpdaters;
mUpdaters = mUpdaters->mNext;
delete doomed;
}
}
NS_IMPL_ADDREF(nsXULCommandDispatcher)
NS_IMPL_RELEASE(nsXULCommandDispatcher)
NS_IMETHODIMP
nsXULCommandDispatcher::QueryInterface(REFNSIID iid, void** result)
{
if (! result)
return NS_ERROR_NULL_POINTER;
*result = nsnull;
if (iid.Equals(NS_GET_IID(nsISupports)) ||
iid.Equals(NS_GET_IID(nsIDOMXULCommandDispatcher))) {
*result = NS_STATIC_CAST(nsIDOMXULCommandDispatcher*, this);
}
else if (iid.Equals(NS_GET_IID(nsIDOMFocusListener)) ||
iid.Equals(NS_GET_IID(nsIDOMEventListener))) {
*result = NS_STATIC_CAST(nsIDOMFocusListener*, this);
}
else if (iid.Equals(NS_GET_IID(nsIScriptObjectOwner))) {
*result = NS_STATIC_CAST(nsIScriptObjectOwner*, this);
}
else if (iid.Equals(NS_GET_IID(nsISupportsWeakReference))) {
*result = NS_STATIC_CAST(nsISupportsWeakReference*, this);
}
else {
return NS_NOINTERFACE;
}
NS_ADDREF_THIS();
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::Create(nsIDOMXULCommandDispatcher** aResult)
{
nsXULCommandDispatcher* dispatcher = new nsXULCommandDispatcher();
if (! dispatcher)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = dispatcher;
NS_ADDREF(*aResult);
return NS_OK;
}
////////////////////////////////////////////////////////////////
// nsIDOMXULTracker Interface
NS_IMETHODIMP
nsXULCommandDispatcher::GetFocusedElement(nsIDOMElement** aElement)
{
*aElement = mCurrentElement;
NS_IF_ADDREF(*aElement);
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetFocusedWindow(nsIDOMWindowInternal** aWindow)
{
*aWindow = mCurrentWindow;
NS_IF_ADDREF(*aWindow);
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetFocusedElement(nsIDOMElement* aElement)
{
mCurrentElement = aElement;
// Need to update focus commands when focus switches from
// an element to no element, so don't test mCurrentElement
// before updating.
UpdateCommands(NS_LITERAL_STRING("focus"));
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetFocusedWindow(nsIDOMWindowInternal* aWindow)
{
mCurrentWindow = aWindow;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::AddCommandUpdater(nsIDOMElement* aElement,
const nsAReadableString& aEvents,
const nsAReadableString& aTargets)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
Updater* updater = mUpdaters;
Updater** link = &mUpdaters;
while (updater) {
if (updater->mElement == aElement) {
#ifdef NS_DEBUG
nsCAutoString eventsC, targetsC, aeventsC, atargetsC;
eventsC.AssignWithConversion(updater->mEvents);
targetsC.AssignWithConversion(updater->mTargets);
aeventsC.Assign(NS_ConvertUCS2toUTF8(aEvents));
atargetsC.Assign(NS_ConvertUCS2toUTF8(aTargets));
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] replace %p(events=%s targets=%s) with (events=%s targets=%s)",
this, aElement,
(const char*) eventsC,
(const char*) targetsC,
(const char*) aeventsC,
(const char*) atargetsC));
#endif
// If the updater was already in the list, then replace
// (?) the 'events' and 'targets' filters with the new
// specification.
updater->mEvents = aEvents;
updater->mTargets = aTargets;
return NS_OK;
}
link = &(updater->mNext);
updater = updater->mNext;
}
#ifdef NS_DEBUG
nsCAutoString aeventsC, atargetsC;
aeventsC.Assign(NS_ConvertUCS2toUTF8(aEvents));
atargetsC.Assign(NS_ConvertUCS2toUTF8(aTargets));
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] add %p(events=%s targets=%s)",
this, aElement,
(const char*) aeventsC,
(const char*) atargetsC));
#endif
// If we get here, this is a new updater. Append it to the list.
updater = new Updater(aElement, aEvents, aTargets);
if (! updater)
return NS_ERROR_OUT_OF_MEMORY;
*link = updater;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::RemoveCommandUpdater(nsIDOMElement* aElement)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
Updater* updater = mUpdaters;
Updater** link = &mUpdaters;
while (updater) {
if (updater->mElement == aElement) {
#ifdef NS_DEBUG
nsCAutoString eventsC, targetsC;
eventsC.AssignWithConversion(updater->mEvents);
targetsC.AssignWithConversion(updater->mTargets);
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] remove %p(events=%s targets=%s)",
this, aElement,
(const char*) eventsC,
(const char*) targetsC));
#endif
*link = updater->mNext;
delete updater;
return NS_OK;
}
link = &(updater->mNext);
updater = updater->mNext;
}
// Hmm. Not found. Oh well.
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::UpdateCommands(const nsAReadableString& aEventName)
{
nsresult rv;
nsAutoString id;
if (mCurrentElement) {
rv = mCurrentElement->GetAttribute(NS_ConvertASCIItoUCS2("id"), id);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get element's id");
if (NS_FAILED(rv)) return rv;
}
#if 0
{
char* actionString = aEventName.ToNewCString();
printf("Doing UpdateCommands(\"%s\")\n", actionString);
free(actionString);
}
#endif
for (Updater* updater = mUpdaters; updater != nsnull; updater = updater->mNext) {
// Skip any nodes that don't match our 'events' or 'targets'
// filters.
if (! Matches(updater->mEvents, aEventName))
continue;
if (! Matches(updater->mTargets, id))
continue;
nsCOMPtr<nsIContent> content = do_QueryInterface(updater->mElement);
NS_ASSERTION(content != nsnull, "not an nsIContent");
if (! content)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIDocument> document;
rv = content->GetDocument(*getter_AddRefs(document));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get document");
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(document != nsnull, "element has no document");
if (! document)
continue;
#ifdef NS_DEBUG
nsCAutoString aeventnameC;
aeventnameC.Assign(NS_ConvertUCS2toUTF8(aEventName));
PR_LOG(gLog, PR_LOG_ALWAYS,
("xulcmd[%p] update %p event=%s",
this, updater->mElement,
(const char*) aeventnameC));
#endif
PRInt32 count = document->GetNumberOfShells();
for (PRInt32 i = 0; i < count; i++) {
nsCOMPtr<nsIPresShell> shell = dont_AddRef(document->GetShellAt(i));
if (! shell)
continue;
// Retrieve the context in which our DOM event will fire.
nsCOMPtr<nsIPresContext> context;
rv = shell->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(rv)) return rv;
// Handle the DOM event
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_XUL_COMMAND_UPDATE;
content->HandleDOMEvent(context, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetControllers(nsIControllers** aResult)
{
//XXX: we should fix this so there's a generic interface that describes controllers,
// so this code would have no special knowledge of what object might have controllers.
if (mCurrentElement) {
nsCOMPtr<nsIDOMXULElement> xulElement = do_QueryInterface(mCurrentElement);
if (xulElement)
return xulElement->GetControllers(aResult);
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextArea = do_QueryInterface(mCurrentElement);
if (htmlTextArea)
return htmlTextArea->GetControllers(aResult);
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement = do_QueryInterface(mCurrentElement);
if (htmlInputElement)
return htmlInputElement->GetControllers(aResult);
}
else if (mCurrentWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(mCurrentWindow);
if (domWindow)
return domWindow->GetControllers(aResult);
}
*aResult = nsnull;
return NS_OK;
}
/////
// nsIDOMFocusListener
/////
nsresult
nsXULCommandDispatcher::Focus(nsIDOMEvent* aEvent)
{
if (mSuppressFocus)
return NS_OK;
nsCOMPtr<nsIDOMEventTarget> t;
aEvent->GetOriginalTarget(getter_AddRefs(t));
#if 0
printf("%d : Focus occurred on: ", this);
nsCOMPtr<nsIDOMElement> domDebugElement = do_QueryInterface(t);
if (domDebugElement) {
printf("A Focusable DOM Element");
}
nsCOMPtr<nsIDOMDocument> domDebugDocument = do_QueryInterface(t);
if (domDebugDocument) {
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(t);
if (htmlDoc) {
printf("Window with an HTML doc (happens twice)");
}
else printf("Window with a XUL doc (happens twice)");
}
printf("\n");
#endif /* DEBUG_hyatt */
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(t);
if (domElement && (domElement != mCurrentElement)) {
SetFocusedElement(domElement);
// Also set focus to our innermost window.
// XXX Must be done for the Ender case, since ender causes a blur,
// but we don't hear the subsequent focus to the Ender window.
nsCOMPtr<nsIDOMDocument> ownerDoc;
domElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
nsCOMPtr<nsIDOMWindowInternal> domWindow;
GetParentWindowFromDocument(ownerDoc, getter_AddRefs(domWindow));
if (domWindow)
SetFocusedWindow(domWindow);
}
else {
// We're focusing a window. We only want to do an update commands
// if no element is focused.
nsCOMPtr<nsIDOMWindowInternal> domWindow;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(t);
if (domDoc) {
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
if (domWindow) {
SetFocusedWindow(domWindow);
if (mCurrentElement) {
// Make sure this element is in our window. If not, we
// should clear this field.
nsCOMPtr<nsIDOMDocument> ownerDoc;
mCurrentElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
nsCOMPtr<nsIDOMDocument> windowDoc;
mCurrentWindow->GetDocument(getter_AddRefs(windowDoc));
if (ownerDoc != windowDoc)
mCurrentElement = nsnull;
}
if (!mCurrentElement)
UpdateCommands(NS_LITERAL_STRING("focus"));
}
}
}
return NS_OK;
}
nsresult
nsXULCommandDispatcher::Blur(nsIDOMEvent* aEvent)
{
if (mSuppressFocus)
return NS_OK;
nsCOMPtr<nsIDOMEventTarget> t;
aEvent->GetOriginalTarget(getter_AddRefs(t));
#if 0
printf("%d : Blur occurred on: ", this);
nsCOMPtr<nsIDOMElement> domDebugElement = do_QueryInterface(t);
if (domDebugElement) {
printf("A Focusable DOM Element");
}
nsCOMPtr<nsIDOMDocument> domDebugDocument = do_QueryInterface(t);
if (domDebugDocument) {
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(t);
if (htmlDoc) {
printf("Window with an HTML doc (happens twice)");
}
else printf("Window with a XUL doc (happens twice)");
}
printf("\n");
#endif /* DEBUG_hyatt */
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(t);
if (domElement) {
SetFocusedElement(nsnull);
}
nsCOMPtr<nsIDOMWindowInternal> domWindow;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(t);
if (domDoc) {
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
if (domWindow)
SetFocusedWindow(nsnull);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// nsIScriptObjectOwner interface
NS_IMETHODIMP
nsXULCommandDispatcher::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptXULCommandDispatcher(aContext, (nsISupports *)(nsIDOMXULCommandDispatcher*)this, global, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return res;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
PRBool
nsXULCommandDispatcher::Matches(const nsString& aList,
const nsAReadableString& aElement)
{
if (aList.Equals(NS_LITERAL_STRING("*")))
return PR_TRUE; // match _everything_!
PRInt32 indx = aList.Find((const PRUnichar *)nsPromiseFlatString(aElement).get());
if (indx == -1)
return PR_FALSE; // not in the list at all
// okay, now make sure it's not a substring snafu; e.g., 'ur'
// found inside of 'blur'.
if (indx > 0) {
PRUnichar ch = aList[indx - 1];
if (! nsCRT::IsAsciiSpace(ch) && ch != PRUnichar(','))
return PR_FALSE;
}
if (indx + aElement.Length() < aList.Length()) {
PRUnichar ch = aList[indx + aElement.Length()];
if (! nsCRT::IsAsciiSpace(ch) && ch != PRUnichar(','))
return PR_FALSE;
}
return PR_TRUE;
}
nsresult
nsXULCommandDispatcher::GetParentWindowFromDocument(nsIDOMDocument* aDocument, nsIDOMWindowInternal** aWindow)
{
nsCOMPtr<nsIDocument> objectOwner = do_QueryInterface(aDocument);
if(!objectOwner) return NS_OK;
nsCOMPtr<nsIScriptGlobalObject> globalObject;
objectOwner->GetScriptGlobalObject(getter_AddRefs(globalObject));
if(!globalObject) return NS_OK;
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(globalObject);
*aWindow = domWindow;
NS_IF_ADDREF(*aWindow);
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetControllerForCommand(const nsAReadableString& aCommand, nsIController** _retval)
{
nsPromiseFlatString flatCommand(aCommand);
const PRUnichar *command = flatCommand.get();
*_retval = nsnull;
nsCOMPtr<nsIControllers> controllers;
GetControllers(getter_AddRefs(controllers));
if(controllers) {
nsCOMPtr<nsIController> controller;
controllers->GetControllerForCommand(command, getter_AddRefs(controller));
if(controller) {
*_retval = controller;
NS_ADDREF(*_retval);
return NS_OK;
}
}
nsCOMPtr<nsPIDOMWindow> currentWindow;
if (mCurrentElement) {
// Move up to the window.
nsCOMPtr<nsIDOMDocument> domDoc;
mCurrentElement->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMWindowInternal> domWindow;
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
currentWindow = do_QueryInterface(domWindow);
}
else if (mCurrentWindow) {
nsCOMPtr<nsPIDOMWindow> privateWin = do_QueryInterface(mCurrentWindow);
privateWin->GetPrivateParent(getter_AddRefs(currentWindow));
}
else return NS_OK;
while(currentWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(currentWindow);
if(domWindow) {
nsCOMPtr<nsIControllers> controllers2;
domWindow->GetControllers(getter_AddRefs(controllers2));
if(controllers2) {
nsCOMPtr<nsIController> controller;
controllers2->GetControllerForCommand(command, getter_AddRefs(controller));
if(controller) {
*_retval = controller;
NS_ADDREF(*_retval);
return NS_OK;
}
}
}
nsCOMPtr<nsPIDOMWindow> parentPWindow = currentWindow;
parentPWindow->GetPrivateParent(getter_AddRefs(currentWindow));
}
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetSuppressFocusScroll(PRBool* aSuppressFocusScroll)
{
*aSuppressFocusScroll = mSuppressFocusScroll;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetSuppressFocusScroll(PRBool aSuppressFocusScroll)
{
mSuppressFocusScroll = aSuppressFocusScroll;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetSuppressFocus(PRBool* aSuppressFocus)
{
if(mSuppressFocus)
*aSuppressFocus = PR_TRUE;
else
*aSuppressFocus = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetSuppressFocus(PRBool aSuppressFocus)
{
if(aSuppressFocus)
++mSuppressFocus;
else if(mSuppressFocus > 0)
--mSuppressFocus;
//printf("mSuppressFocus == %d\n", mSuppressFocus);
// we are unsuppressing after activating, so update focus-related commands
// we need this to update commands in the case where an element is focussed.
if (!mSuppressFocus && mCurrentElement)
UpdateCommands(NS_LITERAL_STRING("focus"));
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::GetActive(PRBool* aActive)
{
//if(!mFocusInitialized)
// return PR_TRUE;
*aActive = mActive;
return NS_OK;
}
NS_IMETHODIMP
nsXULCommandDispatcher::SetActive(PRBool aActive)
{
if(!mFocusInitialized)
mFocusInitialized = PR_TRUE;
mActive = aActive;
return NS_OK;
}

Просмотреть файл

@ -1,119 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
* Contributor(s):
*/
/*
This is the focus manager for XUL documents.
*/
#ifndef nsXULCommandDispatcher_h__
#define nsXULCommandDispatcher_h__
#include "nsCOMPtr.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIDOMFocusListener.h"
#include "nsIScriptObjectOwner.h"
#include "nsWeakReference.h"
#include "nsIDOMNode.h"
#include "nsString.h"
class nsIDOMElement;
class nsPIDOMWindow;
class nsXULCommandDispatcher : public nsIDOMXULCommandDispatcher,
public nsIDOMFocusListener,
public nsIScriptObjectOwner,
public nsSupportsWeakReference
{
protected:
nsXULCommandDispatcher(void);
virtual ~nsXULCommandDispatcher(void);
public:
static NS_IMETHODIMP
Create(nsIDOMXULCommandDispatcher** aResult);
// nsISupports
NS_DECL_ISUPPORTS
// nsIDOMXULCommandDispatcher interface
NS_DECL_IDOMXULCOMMANDDISPATCHER
// nsIDOMFocusListener
virtual nsresult Focus(nsIDOMEvent* aEvent);
virtual nsresult Blur(nsIDOMEvent* aEvent);
// nsIDOMEventListener
virtual nsresult HandleEvent(nsIDOMEvent* anEvent) { return NS_OK; };
// nsIScriptObjectOwner interface
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
public:
static nsresult GetParentWindowFromDocument(nsIDOMDocument* aElement, nsIDOMWindowInternal** aWindow);
protected:
void* mScriptObject; // ????
// XXX THis was supposed to be WEAK, but c'mon, that's an accident
// waiting to happen! If somebody deletes the node, then asks us
// for the focus, we'll get killed!
nsCOMPtr<nsIDOMElement> mCurrentElement; // [OWNER]
nsCOMPtr<nsIDOMWindowInternal> mCurrentWindow; // [OWNER]
//PRBool mSuppressFocus;
PRUint32 mSuppressFocus;
PRBool mSuppressFocusScroll;
PRBool mActive;
PRBool mFocusInitialized;
class Updater {
public:
Updater(nsIDOMElement* aElement,
const nsAReadableString& aEvents,
const nsAReadableString& aTargets)
: mElement(aElement),
mEvents(aEvents),
mTargets(aTargets),
mNext(nsnull)
{}
nsIDOMElement* mElement; // [WEAK]
nsString mEvents;
nsString mTargets;
Updater* mNext;
};
Updater* mUpdaters;
PRBool Matches(const nsString& aList,
const nsAReadableString& aElement);
};
#endif // nsXULCommandDispatcher_h__

Просмотреть файл

@ -1413,11 +1413,6 @@ nsXULDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
if (mRootContent)
mRootContent->SetDocument(nsnull, PR_TRUE, PR_TRUE);
// Break circular reference for the case where the currently
// focused window is ourself.
if (mCommandDispatcher)
mCommandDispatcher->SetFocusedWindow(nsnull);
// set all builder references to document to nsnull -- out of band notification
// to break ownership cycle
if (mBuilders) {
@ -3828,18 +3823,9 @@ nsXULDocument::Init()
mNodeInfoManager->Init(mNameSpaceManager);
// Create our command dispatcher and hook it up.
rv = nsXULCommandDispatcher::Create(getter_AddRefs(mCommandDispatcher));
rv = nsXULCommandDispatcher::Create(this, getter_AddRefs(mCommandDispatcher));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a focus tracker");
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMEventListener> commandDispatcher =
do_QueryInterface(mCommandDispatcher);
if (commandDispatcher) {
// Take the focus tracker and add it as an event listener for focus and blur events.
AddEventListener(NS_LITERAL_STRING("focus"), commandDispatcher, PR_TRUE);
AddEventListener(NS_LITERAL_STRING("blur"), commandDispatcher, PR_TRUE);
}
// Get the local store. Yeah, I know. I wish GetService() used a
// 'void**', too.