зеркало из https://github.com/mozilla/pjs.git
moving modal dialog code to one central location, where things won't be allocated and released in separate methods
This commit is contained in:
Родитель
70e2ddfa1f
Коммит
2177440c9e
|
@ -1787,14 +1787,11 @@ nsBrowserAppCore::ExecuteScript(nsIScriptContext * aContext, const nsString& aSc
|
|||
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBrowserAppCore::DoDialog()
|
||||
{
|
||||
/* (adapted from nsToolkitCore. No one's using this function, are they!?)
|
||||
*/
|
||||
// (adapted from nsToolkitCore)
|
||||
nsresult rv;
|
||||
nsIAppShellService *appShell;
|
||||
nsIWebShellWindow *window;
|
||||
|
||||
window = nsnull;
|
||||
|
@ -1804,19 +1801,11 @@ nsBrowserAppCore::DoDialog()
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID,
|
||||
(nsISupports**) &appShell);
|
||||
NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
appShell->CreateDialogWindow(mWebShellWin, urlObj, PR_TRUE, window,
|
||||
nsnull, nsnull, 615, 480);
|
||||
nsServiceManager::ReleaseService(kAppShellServiceCID, appShell);
|
||||
// window->Resize(300, 200, PR_TRUE); (until Resize gets moved into nsIWebShellWindow)
|
||||
|
||||
if (window != nsnull)
|
||||
window->ShowModal();
|
||||
|
||||
rv = appShell->RunModalDialog(mWebShellWin, urlObj, window, nsnull, nsnull, 300, 200);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
class nsIScriptContext;
|
||||
|
||||
static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID);
|
||||
static NS_DEFINE_IID(kIAppShellServiceIID, NS_IAPPSHELL_SERVICE_IID);
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
|
||||
|
||||
|
@ -142,7 +141,6 @@ NS_IMETHODIMP
|
|||
nsToolkitCore::ShowDialog(const nsString& aUrl, nsIDOMWindow* aParent) {
|
||||
|
||||
nsresult rv;
|
||||
nsIAppShellService *appShell;
|
||||
nsIWebShellWindow *window;
|
||||
|
||||
window = nsnull;
|
||||
|
@ -152,8 +150,7 @@ nsToolkitCore::ShowDialog(const nsString& aUrl, nsIDOMWindow* aParent) {
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID,
|
||||
(nsISupports**) &appShell);
|
||||
NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -161,7 +158,6 @@ nsToolkitCore::ShowDialog(const nsString& aUrl, nsIDOMWindow* aParent) {
|
|||
DOMWindowToWebShellWindow(aParent, &parent);
|
||||
appShell->CreateDialogWindow(parent, urlObj, PR_TRUE, window,
|
||||
nsnull, nsnull, 615, 480);
|
||||
nsServiceManager::ReleaseService(kAppShellServiceCID, appShell);
|
||||
|
||||
if (window != nsnull)
|
||||
window->Show(PR_TRUE);
|
||||
|
@ -173,7 +169,6 @@ NS_IMETHODIMP
|
|||
nsToolkitCore::ShowWindow(const nsString& aUrl, nsIDOMWindow* aParent) {
|
||||
|
||||
nsresult rv;
|
||||
nsIAppShellService *appShell;
|
||||
nsIWebShellWindow *window;
|
||||
|
||||
window = nsnull;
|
||||
|
@ -183,8 +178,7 @@ nsToolkitCore::ShowWindow(const nsString& aUrl, nsIDOMWindow* aParent) {
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID,
|
||||
(nsISupports**) &appShell);
|
||||
NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -192,7 +186,6 @@ nsToolkitCore::ShowWindow(const nsString& aUrl, nsIDOMWindow* aParent) {
|
|||
DOMWindowToWebShellWindow(aParent, &parent);
|
||||
appShell->CreateTopLevelWindow(parent, urlObj, PR_TRUE, window,
|
||||
nsnull, nsnull, 615, 480);
|
||||
nsServiceManager::ReleaseService(kAppShellServiceCID, appShell);
|
||||
|
||||
if (window != nsnull)
|
||||
window->Show(PR_TRUE);
|
||||
|
@ -284,7 +277,6 @@ nsToolkitCore::ShowWindowWithArgs(const nsString& aUrl,
|
|||
const nsString& aArgs) {
|
||||
|
||||
nsresult rv;
|
||||
nsIAppShellService *appShell;
|
||||
nsIWebShellWindow *window;
|
||||
|
||||
window = nsnull;
|
||||
|
@ -294,8 +286,7 @@ nsToolkitCore::ShowWindowWithArgs(const nsString& aUrl,
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID,
|
||||
(nsISupports**) &appShell);
|
||||
NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -305,7 +296,6 @@ nsToolkitCore::ShowWindowWithArgs(const nsString& aUrl,
|
|||
cb = nsDontQueryInterface<nsArgCallbacks>( new nsArgCallbacks( aArgs ) );
|
||||
appShell->CreateTopLevelWindow(parent, urlObj, PR_TRUE, window,
|
||||
nsnull, cb, 615, 650);
|
||||
nsServiceManager::ReleaseService(kAppShellServiceCID, appShell);
|
||||
|
||||
if (window != nsnull)
|
||||
window->Show(PR_TRUE);
|
||||
|
@ -317,7 +307,6 @@ NS_IMETHODIMP
|
|||
nsToolkitCore::ShowModalDialog(const nsString& aUrl, nsIDOMWindow* aParent) {
|
||||
|
||||
nsresult rv;
|
||||
nsIAppShellService *appShell;
|
||||
nsIWebShellWindow *window;
|
||||
|
||||
window = nsnull;
|
||||
|
@ -327,50 +316,13 @@ nsToolkitCore::ShowModalDialog(const nsString& aUrl, nsIDOMWindow* aParent) {
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID,
|
||||
(nsISupports**) &appShell);
|
||||
NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// First push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
nsIEventQueueService *eQueueService;
|
||||
nsCOMPtr<nsIEventQueue> innerQueue;
|
||||
if (NS_FAILED(rv = nsServiceManager::GetService(kEventQueueServiceCID,
|
||||
kIEventQueueServiceIID,
|
||||
(nsISupports **)&eQueueService))) {
|
||||
NS_ERROR("Unable to obtain queue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN32 // XXX: Won't work with any other platforms yet.
|
||||
eQueueService->PushThreadEventQueue();
|
||||
#endif // XP_WIN32
|
||||
|
||||
nsCOMPtr<nsIWebShellWindow> parent;
|
||||
DOMWindowToWebShellWindow(aParent, &parent);
|
||||
appShell->CreateDialogWindow(parent, urlObj, PR_TRUE, window,
|
||||
nsnull, nsnull, 615, 480);
|
||||
nsServiceManager::ReleaseService(kAppShellServiceCID, appShell);
|
||||
|
||||
if (window != nsnull) {
|
||||
nsCOMPtr<nsIWidget> parentWindowWidgetThing;
|
||||
nsresult gotParent;
|
||||
gotParent = parent ? parent->GetWidget(*getter_AddRefs(parentWindowWidgetThing)) :
|
||||
NS_ERROR_FAILURE;
|
||||
// Windows OS is the only one that needs the parent disabled, or cares
|
||||
// arguably this should be done by the new window, within ShowModal...
|
||||
if (NS_SUCCEEDED(gotParent))
|
||||
parentWindowWidgetThing->Enable(PR_FALSE);
|
||||
window->ShowModal(); // XXX This method pops the queue itself. Ugh. There should really be one
|
||||
// call for all of this.
|
||||
if (NS_SUCCEEDED(gotParent))
|
||||
parentWindowWidgetThing->Enable(PR_TRUE);
|
||||
}
|
||||
|
||||
// Release the event queue
|
||||
nsServiceManager::ReleaseService(kEventQueueServiceCID, eQueueService);
|
||||
|
||||
rv = appShell->RunModalDialog(parent, urlObj, window, nsnull, nsnull, 615, 480);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -390,8 +342,9 @@ void nsToolkitCore::DOMWindowToWebShellWindow(
|
|||
nsIDOMWindow *DOMWindow,
|
||||
nsCOMPtr<nsIWebShellWindow> *webWindow) const {
|
||||
|
||||
*webWindow = 0;
|
||||
if (!DOMWindow)
|
||||
return; // with webWindow unchanged -- its constructor gives it a null ptr
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalScript(do_QueryInterface(DOMWindow));
|
||||
nsCOMPtr<nsIWebShell> webshell, rootWebshell;
|
||||
|
|
|
@ -59,6 +59,11 @@ public:
|
|||
nsIWebShellWindow*& aResult, nsIStreamObserver* anObserver,
|
||||
nsIXULWindowCallbacks *aCallbacks,
|
||||
PRInt32 aInitialWidth, PRInt32 aInitialHeight) = 0;
|
||||
NS_IMETHOD RunModalDialog( nsIWebShellWindow * aParent,
|
||||
nsIURL* aUrl,
|
||||
nsIWebShellWindow*& aResult, nsIStreamObserver* anObserver,
|
||||
nsIXULWindowCallbacks *aCallbacks,
|
||||
PRInt32 aInitialWidth, PRInt32 aInitialHeight) = 0;
|
||||
NS_IMETHOD CloseTopLevelWindow(nsIWebShellWindow* aWindow) = 0;
|
||||
NS_IMETHOD RegisterTopLevelWindow(nsIWebShellWindow* aWindow) = 0;
|
||||
NS_IMETHOD UnregisterTopLevelWindow(nsIWebShellWindow* aWindow) = 0;
|
||||
|
|
|
@ -90,6 +90,11 @@ public:
|
|||
nsIWebShellWindow*& aResult, nsIStreamObserver* anObserver,
|
||||
nsIXULWindowCallbacks *aCallbacks,
|
||||
PRInt32 aInitialWidth, PRInt32 aInitialHeight);
|
||||
NS_IMETHOD RunModalDialog( nsIWebShellWindow * aParent,
|
||||
nsIURL* aUrl,
|
||||
nsIWebShellWindow*& aResult, nsIStreamObserver* anObserver,
|
||||
nsIXULWindowCallbacks *aCallbacks,
|
||||
PRInt32 aInitialWidth, PRInt32 aInitialHeight);
|
||||
NS_IMETHOD CloseTopLevelWindow(nsIWebShellWindow* aWindow);
|
||||
NS_IMETHOD RegisterTopLevelWindow(nsIWebShellWindow* aWindow);
|
||||
NS_IMETHOD UnregisterTopLevelWindow(nsIWebShellWindow* aWindow);
|
||||
|
@ -322,6 +327,62 @@ nsAppShellService::CreateDialogWindow(nsIWebShellWindow * aParent,
|
|||
}
|
||||
|
||||
|
||||
/* CreateDialogWindow, run it modally, and destroy it. To make initial control
|
||||
settings or get information out of the dialog before dismissal, use
|
||||
event handlers. This wrapper method is desirable because of the
|
||||
complications creeping in to the modal window story: there's a lot of setup.
|
||||
See the code.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsAppShellService::RunModalDialog(
|
||||
nsIWebShellWindow *aParent, nsIURL* aUrl,
|
||||
nsIWebShellWindow*& aResult, nsIStreamObserver *anObserver,
|
||||
nsIXULWindowCallbacks *aCallbacks,
|
||||
PRInt32 aInitialWidth, PRInt32 aInitialHeight)
|
||||
{
|
||||
|
||||
nsresult rv;
|
||||
nsIWebShellWindow *window;
|
||||
|
||||
window = nsnull;
|
||||
|
||||
#ifdef XP_PC // XXX: Won't work with any other platforms yet.
|
||||
// First push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
// nsCOMPtr<nsIEventQueue> innerQueue;
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("RunModalDialog unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
eQueueService->PushThreadEventQueue();
|
||||
#endif
|
||||
|
||||
rv = CreateDialogWindow(aParent, aUrl, PR_TRUE, window, anObserver, nsnull,
|
||||
aInitialWidth, aInitialHeight);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIWidget> parentWindowWidgetThing;
|
||||
nsresult gotParent;
|
||||
gotParent = aParent ? aParent->GetWidget(*getter_AddRefs(parentWindowWidgetThing)) :
|
||||
NS_ERROR_FAILURE;
|
||||
// Windows OS wants the parent disabled for modality
|
||||
if (NS_SUCCEEDED(gotParent))
|
||||
parentWindowWidgetThing->Enable(PR_FALSE);
|
||||
window->ShowModal();
|
||||
if (NS_SUCCEEDED(gotParent))
|
||||
parentWindowWidgetThing->Enable(PR_TRUE);
|
||||
}
|
||||
|
||||
// Release the event queue
|
||||
#ifdef XP_PC // XXX Won't work on other platforms yet
|
||||
eQueueService->PopThreadEventQueue();
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Register a new top level window (created elsewhere)
|
||||
*/
|
||||
|
|
|
@ -899,45 +899,37 @@ NS_IMETHODIMP
|
|||
nsWebShellWindow::NewWebShell(PRUint32 aChromeMask, PRBool aVisible,
|
||||
nsIWebShell *&aNewWebShell)
|
||||
{
|
||||
#ifdef XP_WIN32 // XXX: Won't work on any other platforms yet. Sigh.
|
||||
// We need to create a new top level window and then enter a nested
|
||||
// loop. Eventually the new window will be told that it has loaded,
|
||||
// at which time we know it is safe to spin out of the nested loop
|
||||
// and allow the opening code to proceed.
|
||||
#ifdef XP_PC // XXX: Won't work on any other platforms yet. Sigh.
|
||||
// We need to create a new top level window and then enter a nested
|
||||
// loop. Eventually the new window will be told that it has loaded,
|
||||
// at which time we know it is safe to spin out of the nested loop
|
||||
// and allow the opening code to proceed.
|
||||
|
||||
// First push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
nsresult rv;
|
||||
nsIAppShellService *appShell;
|
||||
nsIEventQueueService *eQueueService;
|
||||
nsCOMPtr<nsIEventQueue> outerQueue;
|
||||
nsCOMPtr<nsIEventQueue> innerQueue;
|
||||
if (NS_FAILED(rv = nsServiceManager::GetService(kEventQueueServiceCID,
|
||||
kIEventQueueServiceIID,
|
||||
(nsISupports **)&eQueueService))) {
|
||||
NS_ERROR("Unable to obtain queue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
eQueueService->PushThreadEventQueue();
|
||||
// First push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Unable to obtain queue service.");
|
||||
return rv;
|
||||
}
|
||||
eQueueService->PushThreadEventQueue();
|
||||
|
||||
nsCOMPtr<nsIURL> urlObj;
|
||||
rv = NS_NewURL(getter_AddRefs(urlObj), "chrome://navigator/content/");
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID,
|
||||
(nsISupports**) &appShell);
|
||||
NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIWebShellWindow> newWindow;
|
||||
nsCOMPtr<nsIWebShellWindow> newWindow;
|
||||
appShell->CreateTopLevelWindow(nsnull, urlObj, PR_FALSE, *getter_AddRefs(newWindow),
|
||||
nsnull, nsnull, 615, 480);
|
||||
nsServiceManager::ReleaseService(kAppShellServiceCID, appShell);
|
||||
|
||||
// Spin into the modal loop.
|
||||
nsIAppShell *subshell;
|
||||
// Spin into the modal loop.
|
||||
nsIAppShell *subshell;
|
||||
rv = nsComponentManager::CreateInstance(kAppShellCID, nsnull, kIAppShellIID, (void**)&subshell);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -946,10 +938,10 @@ nsWebShellWindow::NewWebShell(PRUint32 aChromeMask, PRBool aVisible,
|
|||
subshell->Spinup(); // Spin up
|
||||
|
||||
// Specify that we want the window to remain locked until the chrome has loaded.
|
||||
newWindow->LockUntilChromeLoad();
|
||||
newWindow->LockUntilChromeLoad();
|
||||
|
||||
PRBool locked = PR_FALSE;
|
||||
newWindow->GetLockedState(locked);
|
||||
PRBool locked = PR_FALSE;
|
||||
newWindow->GetLockedState(locked);
|
||||
while (NS_SUCCEEDED(rv) && locked) {
|
||||
void *data;
|
||||
PRBool isRealEvent;
|
||||
|
@ -957,25 +949,24 @@ nsWebShellWindow::NewWebShell(PRUint32 aChromeMask, PRBool aVisible,
|
|||
rv = subshell->GetNativeEvent(isRealEvent, data);
|
||||
subshell->DispatchNativeEvent(isRealEvent, data);
|
||||
|
||||
newWindow->GetLockedState(locked);
|
||||
newWindow->GetLockedState(locked);
|
||||
}
|
||||
|
||||
// Get rid of the nested UI thread queue used for netlib, and release the event queue service.
|
||||
eQueueService->PopThreadEventQueue();
|
||||
nsServiceManager::ReleaseService(kEventQueueServiceCID, eQueueService);
|
||||
// Get rid of the nested UI thread queue used for netlib, and release the event queue service.
|
||||
eQueueService->PopThreadEventQueue();
|
||||
|
||||
subshell->Spindown();
|
||||
NS_RELEASE(subshell);
|
||||
|
||||
// We're out of the nested loop.
|
||||
// We're out of the nested loop.
|
||||
// During the layout of the new window, all content shells were located and placed
|
||||
// into the new window's content shell array. Locate the "content area" content
|
||||
// shell.
|
||||
if (NS_FAILED(rv = newWindow->GetContentShellById("content", &aNewWebShell))) {
|
||||
NS_ERROR("Unable to obtain a browser content shell.");
|
||||
return rv;
|
||||
}
|
||||
#endif // XP_WIN32
|
||||
// into the new window's content shell array. Locate the "content area" content
|
||||
// shell.
|
||||
if (NS_FAILED(rv = newWindow->GetContentShellById("content", &aNewWebShell))) {
|
||||
NS_ERROR("Unable to obtain a browser content shell.");
|
||||
return rv;
|
||||
}
|
||||
#endif // XP_PC
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1031,9 +1022,6 @@ nsWebShellWindow::ShowModal()
|
|||
NS_IMETHODIMP
|
||||
nsWebShellWindow::ShowModalInternal()
|
||||
{
|
||||
// XXX This sucks right now. The pushing of an event queue has to happen outside of this function
|
||||
// before the CreateTopLevelWindow, and the popping has to happen here. This really needs to all be
|
||||
// pulled out into a new function so that the flow can be cleaner.
|
||||
nsresult rv;
|
||||
nsIAppShell *subshell;
|
||||
|
||||
|
@ -1042,14 +1030,6 @@ nsWebShellWindow::ShowModalInternal()
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsIEventQueueService *eQueueService;
|
||||
if (NS_FAILED(rv = nsServiceManager::GetService(kEventQueueServiceCID,
|
||||
kIEventQueueServiceIID,
|
||||
(nsISupports **)&eQueueService))) {
|
||||
NS_ERROR("Unable to obtain queue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
subshell->Create(0, nsnull);
|
||||
subshell->Spinup();
|
||||
|
||||
|
@ -1069,16 +1049,10 @@ nsWebShellWindow::ShowModalInternal()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef XP_WIN32 // XXX Won't work on other platforms yet
|
||||
eQueueService->PopThreadEventQueue();
|
||||
#endif // XP_WIN32
|
||||
|
||||
subshell->Spindown();
|
||||
NS_RELEASE(window);
|
||||
NS_RELEASE(subshell);
|
||||
|
||||
nsServiceManager::ReleaseService(kEventQueueServiceCID, eQueueService);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче