Commit d0d7a850 authored by Tatiana Meshkova's avatar Tatiana Meshkova

Added support for exiting from event loop when prompt did not receive response

parent 08959968
......@@ -69,15 +69,6 @@ EmbedPromptRegister::Init()
rv = cr->RegisterFactory(promptCID, "EmbedLite Prompt",
"@mozilla.org/prompter;1", f);
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (observerService) {
observerService->AddObserver(this,
"outer-window-destroyed",
true);
}
f = new mozilla::embedlite::GenericFactory(nsEmbedAlertsServiceConstructor);
if (!f) {
NS_WARNING("Unable to create factory for component");
......
......@@ -11,7 +11,7 @@
#include "nsIObserver.h"
class EmbedPromptRegister : public nsIObserver,
public nsSupportsWeakReference
public nsSupportsWeakReference
{
public:
EmbedPromptRegister();
......
......@@ -25,11 +25,47 @@
#include "nsIProtocolHandler.h"
#include "nsIDOMWindow.h"
#include "nsIEmbedLiteJSON.h"
#include "nsIObserverService.h"
// Prompt Factory Implementation
using namespace mozilla::embedlite;
EmbedPromptOuterObserver::EmbedPromptOuterObserver(IDestroyNotification* aNotifier, nsIDOMWindow* aWin)
: mNotifier(aNotifier)
, mWin(aWin)
{
mService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (mService) {
mService->AddObserver(this, "outer-window-destroyed", false);
}
}
void EmbedPromptOuterObserver::OnDestroy()
{
mService->RemoveObserver(this, "outer-window-destroyed");
}
EmbedPromptOuterObserver::~EmbedPromptOuterObserver()
{
OnDestroy();
}
NS_IMPL_ISUPPORTS2(EmbedPromptOuterObserver, nsIObserver, nsSupportsWeakReference)
NS_IMETHODIMP
EmbedPromptOuterObserver::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (!strcmp(aTopic, "outer-window-destroyed")) {
OnDestroy();
mNotifier->OnDestroyNotification();
mNotifier = nullptr;
}
return NS_OK;
}
EmbedPromptFactory::EmbedPromptFactory()
{
}
......@@ -63,6 +99,13 @@ EmbedPromptService::EmbedPromptService(nsIDOMWindow* aWin)
, mModalDepth(0)
{
mService = do_GetService("@mozilla.org/embedlite-app-service;1");
mOuterService = new EmbedPromptOuterObserver(this, aWin);
}
void
EmbedPromptService::OnDestroyNotification()
{
CancelResponse();
}
EmbedPromptService::~EmbedPromptService()
......@@ -79,11 +122,20 @@ EmbedPromptService::Alert(const PRUnichar* aDialogTitle,
return NS_OK;
}
void
EmbedPromptService::CancelResponse()
{
std::map<uint32_t, EmbedPromptResponse>::iterator it;
for (it = mResponseMap.begin(); it != mResponseMap.end(); it++) {
EmbedPromptResponse& response = it->second;
mModalDepth--;
}
}
NS_IMETHODIMP
EmbedPromptService::OnMessageReceived(const char* messageName, const PRUnichar* message)
{
nsCOMPtr<nsIEmbedLiteJSON> json = do_GetService("@mozilla.org/embedlite-json;1");
printf(">>>>>>Func:%s::%d name:%s, msg:%s\n", __PRETTY_FUNCTION__, __LINE__, messageName, NS_ConvertUTF16toUTF8(message).get());
nsCOMPtr<nsIPropertyBag2> root;
NS_ENSURE_SUCCESS(json->ParseJSON(nsDependentString(message), getter_AddRefs(root)), NS_ERROR_FAILURE);
......@@ -106,6 +158,31 @@ EmbedPromptService::OnMessageReceived(const char* messageName, const PRUnichar*
return NS_OK;
}
uint32_t
EmbedPromptService::CheckWinID()
{
uint32_t winid = 0;
mService->GetIDByWindow(mWin, &winid);
if (!winid) {
mOuterService->OnDestroy();
mOuterService = nullptr;
}
return winid;
}
uint32_t
EmbedAuthPromptService::CheckWinID()
{
uint32_t winid = 0;
mService->GetIDByWindow(mWin, &winid);
if (!winid) {
mOuterService->OnDestroy();
mOuterService = nullptr;
}
return winid;
}
NS_IMETHODIMP
EmbedPromptService::AlertCheck(const PRUnichar* aDialogTitle,
const PRUnichar* aDialogText,
......@@ -150,7 +227,7 @@ EmbedPromptService::AlertCheck(const PRUnichar* aDialogTitle,
while (mModalDepth == origModalDepth && NS_SUCCEEDED(rv)) {
bool processedEvent;
rv = thread->ProcessNextEvent(true, &processedEvent);
if (NS_SUCCEEDED(rv) && !processedEvent) {
if (NS_SUCCEEDED(rv) && (!processedEvent || !CheckWinID())) {
rv = NS_ERROR_UNEXPECTED;
}
}
......@@ -236,7 +313,7 @@ EmbedPromptService::ConfirmCheck(const PRUnichar* aDialogTitle,
while (mModalDepth == origModalDepth && NS_SUCCEEDED(rv)) {
bool processedEvent;
rv = thread->ProcessNextEvent(true, &processedEvent);
if (NS_SUCCEEDED(rv) && !processedEvent) {
if (NS_SUCCEEDED(rv) && (!processedEvent || !CheckWinID())) {
rv = NS_ERROR_UNEXPECTED;
}
}
......@@ -333,7 +410,7 @@ EmbedPromptService::Prompt(const PRUnichar* aDialogTitle,
while (mModalDepth == origModalDepth && NS_SUCCEEDED(rv)) {
bool processedEvent;
rv = thread->ProcessNextEvent(true, &processedEvent);
if (NS_SUCCEEDED(rv) && !processedEvent) {
if (NS_SUCCEEDED(rv) && (!processedEvent || !CheckWinID())) {
rv = NS_ERROR_UNEXPECTED;
}
}
......@@ -412,12 +489,29 @@ EmbedAuthPromptService::EmbedAuthPromptService(nsIDOMWindow* aWin)
: mWin(aWin)
{
mService = do_GetService("@mozilla.org/embedlite-app-service;1");
mOuterService = new EmbedPromptOuterObserver(this, mWin);
}
EmbedAuthPromptService::~EmbedAuthPromptService()
{
}
void
EmbedAuthPromptService::CancelResponse()
{
std::map<uint32_t, EmbedPromptResponse>::iterator it;
for (it = mResponseMap.begin(); it != mResponseMap.end(); it++) {
EmbedPromptResponse& response = it->second;
mModalDepth--;
}
}
void
EmbedAuthPromptService::OnDestroyNotification()
{
CancelResponse();
}
NS_IMPL_ISUPPORTS2(EmbedAuthPromptService, nsIAuthPrompt2, nsIEmbedMessageListener)
NS_IMETHODIMP
......@@ -643,7 +737,7 @@ EmbedAuthPromptService::DoSendAsyncPrompt(EmbedAsyncAuthPrompt* mPrompt)
while (mModalDepth == origModalDepth && NS_SUCCEEDED(rv)) {
bool processedEvent;
rv = thread->ProcessNextEvent(true, &processedEvent);
if (NS_SUCCEEDED(rv) && !processedEvent) {
if (NS_SUCCEEDED(rv) && (!processedEvent || !CheckWinID())) {
rv = NS_ERROR_UNEXPECTED;
}
}
......
......@@ -18,9 +18,13 @@
#include "nsDataHashtable.h"
#include "nsIEmbedAppService.h"
#include "nsIChannel.h"
#include "nsWeakReference.h"
#include "nsIObserver.h"
#include <map>
#include <string>
class nsIObserverService;
namespace mozilla {
namespace embedlite {
......@@ -39,7 +43,28 @@ public:
nsString password;
};
class EmbedPromptService : public nsIPrompt, public nsIEmbedMessageListener
class IDestroyNotification
{
public:
virtual void OnDestroyNotification() = 0;
};
class EmbedPromptOuterObserver : public nsIObserver, public nsSupportsWeakReference
{
public:
EmbedPromptOuterObserver(IDestroyNotification* aNotifier, nsIDOMWindow* aWin);
virtual ~EmbedPromptOuterObserver();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
void OnDestroy();
private:
IDestroyNotification* mNotifier;
nsCOMPtr<nsIDOMWindow> mWin;
nsCOMPtr<nsIObserverService> mService;
};
class EmbedPromptService : public nsIPrompt, public nsIEmbedMessageListener, public IDestroyNotification
{
public:
EmbedPromptService(nsIDOMWindow* aWin);
......@@ -48,11 +73,18 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROMPT
NS_DECL_NSIEMBEDMESSAGELISTENER
virtual void OnDestroyNotification();
private:
void CancelResponse();
uint32_t CheckWinID();
nsCOMPtr<nsIDOMWindow> mWin;
int mModalDepth;
nsCOMPtr<nsIEmbedAppService> mService;
std::map<uint32_t, EmbedPromptResponse> mResponseMap;
RefPtr<EmbedPromptOuterObserver> mOuterService;
};
class EmbedAuthPromptService;
......@@ -82,7 +114,7 @@ public:
RefPtr<EmbedAuthPromptService> mService;
};
class EmbedAuthPromptService : public nsIAuthPrompt2, public nsIEmbedMessageListener
class EmbedAuthPromptService : public nsIAuthPrompt2, public nsIEmbedMessageListener, public IDestroyNotification
{
public:
EmbedAuthPromptService(nsIDOMWindow* aWin);
......@@ -98,10 +130,12 @@ public:
const bool& confirmed,
const nsString& username,
const nsString& password);
virtual void OnDestroyNotification();
private:
void DoAsyncPrompt();
void CancelResponse();
uint32_t CheckWinID();
nsCOMPtr<nsIDOMWindow> mWin;
std::map<std::string, EmbedAsyncAuthPrompt*> asyncPrompts;
......@@ -109,6 +143,7 @@ private:
nsCOMPtr<nsIEmbedAppService> mService;
int mModalDepth;
std::map<uint32_t, EmbedPromptResponse> mResponseMap;
RefPtr<EmbedPromptOuterObserver> mOuterService;
};
class EmbedPromptFactory : public nsIPromptFactory
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment