"Turn on app shell component autoloading"

git-svn-id: svn://10.0.0.236/trunk@31670 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
law%netscape.com 1999-05-14 22:02:23 +00:00
parent fce37733eb
commit b253b3940c
9 changed files with 318 additions and 626 deletions

View File

@ -80,6 +80,9 @@ static NS_DEFINE_IID(kIWalletServiceIID, NS_IWALLETSERVICE_IID);
static NS_DEFINE_IID(kWalletServiceCID, NS_WALLETSERVICE_CID);
#endif
// Interface for "unknown content type handler" component/service.
#include "nsIUnknownContentTypeHandler.h"
// Stuff to implement file download dialog.
#include "nsIXULWindowCallbacks.h"
#include "nsIDocumentObserver.h"
@ -136,8 +139,6 @@ static nsresult setAttribute( nsIWebShell *shell,
// nsBrowserAppCore
/////////////////////////////////////////////////////////////////////////
nsIFindComponent *nsBrowserAppCore::mFindComponent = 0;
nsBrowserAppCore::nsBrowserAppCore()
{
if (APP_DEBUG) printf("Created nsBrowserAppCore\n");
@ -740,11 +741,6 @@ nsBrowserAppCore::SetWebShellWindow(nsIDOMWindow* aWin)
if (! aWin)
return NS_ERROR_NULL_POINTER;
#if 0
if (!mContentWindow) {
return NS_ERROR_FAILURE;
}
#endif /* 0 */
nsCOMPtr<nsIScriptGlobalObject> globalObj( do_QueryInterface(aWin) );
if (!globalObj) {
return NS_ERROR_FAILURE;
@ -968,393 +964,6 @@ done:
return NS_OK;
}
// Notice: This is only a temporary home for nsFileDownloadDialog!
// It will be moving to it's own component .h/.cpp file soon.
struct nsFileDownloadDialog : public nsIXULWindowCallbacks,
nsIStreamListener,
nsIDocumentObserver {
// Declare implementation of ISupports stuff.
NS_DECL_ISUPPORTS
// Declare implementations of nsIXULWindowCallbacks interface functions.
NS_IMETHOD ConstructBeforeJavaScript(nsIWebShell *aWebShell);
NS_IMETHOD ConstructAfterJavaScript(nsIWebShell *aWebShell) { return NS_OK; }
// Declare implementations of nsIStreamListener/nsIStreamObserver functions.
NS_IMETHOD GetBindInfo(nsIURL* aURL, nsStreamBindingInfo* aInfo) { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD OnDataAvailable(nsIURL* aURL, nsIInputStream *aIStream, PRUint32 aLength);
NS_IMETHOD OnStartBinding(nsIURL* aURL, const char *aContentType);
NS_IMETHOD OnProgress(nsIURL* aURL, PRUint32 aProgress, PRUint32 aProgressMax);
NS_IMETHOD OnStatus(nsIURL* aURL, const PRUnichar* aMsg);
NS_IMETHOD OnStopBinding(nsIURL* aURL, nsresult aStatus, const PRUnichar* aMsg);
// Declare implementations of nsIDocumentObserver functions.
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD EndReflow(nsIDocument *aDocument, nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent1,
nsIContent* aContent2) { return NS_OK; }
// This one we care about; see implementation below.
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
PRBool aDisabled) { return NS_OK; }
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint) { return NS_OK; }
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument) { return NS_OK; }
// nsFileDownloadDialog stuff
nsFileDownloadDialog( nsIURL *aURL, const char *aContentType );
virtual ~nsFileDownloadDialog() { delete mOutput; delete [] mBuffer; }
void OnSave();
void OnMore();
void OnPick();
void OnClose();
void OnStart();
void OnStop();
void SetWindow( nsIWebShellWindow *aWindow );
private:
nsCOMPtr<nsIURL> mUrl;
nsCOMPtr<nsIWebShell> mWebShell;
nsCOMPtr<nsIWebShellWindow> mWindow;
nsOutputFileStream *mOutput;
nsString mContentType;
nsFileSpec mFileName;
PRUint32 mBufLen;
char * mBuffer;
PRBool mStopped;
enum { kPrompt, kProgress } mMode;
}; // nsFileDownloadDialog
// Standard implementations of addref/release.
NS_IMPL_ADDREF( nsFileDownloadDialog );
NS_IMPL_RELEASE( nsFileDownloadDialog );
NS_IMETHODIMP
nsFileDownloadDialog::QueryInterface(REFNSIID aIID,void** aInstancePtr)
{
if (aInstancePtr == NULL) {
return NS_ERROR_NULL_POINTER;
}
// Always NULL result, in case of failure
*aInstancePtr = NULL;
if (aIID.Equals(nsIDocumentObserver::GetIID())) {
*aInstancePtr = (void*) ((nsIDocumentObserver*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIXULWindowCallbacks::GetIID())) {
*aInstancePtr = (void*) ((nsIXULWindowCallbacks*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_ERROR_NO_INTERFACE;
}
// ctor
nsFileDownloadDialog::nsFileDownloadDialog( nsIURL *aURL, const char *aContentType )
: mUrl( nsDontQueryInterface<nsIURL>(aURL) ),
mWebShell(),
mWindow(),
mOutput(0),
mBufLen( 8192 ),
mBuffer( new char[ mBufLen ] ),
mStopped( PR_FALSE ),
mContentType( aContentType ),
mMode( kPrompt ) {
// Initialize ref count.
NS_INIT_REFCNT();
}
// Do startup stuff from C++ side.
NS_IMETHODIMP
nsFileDownloadDialog::ConstructBeforeJavaScript(nsIWebShell *aWebShell) {
nsresult rv = NS_OK;
// Save web shell pointer.
mWebShell = nsDontQueryInterface<nsIWebShell>( aWebShell );
// Store instance information into dialog's DOM.
const char *loc = 0;
mUrl->GetSpec( &loc );
setAttribute( mWebShell, "data.location", "value", loc );
setAttribute( mWebShell, "data.contentType", "value", mContentType );
// If showing download progress, make target file name known.
if ( mMode == kProgress ) {
setAttribute( mWebShell, "data.fileName", "value", nsString((const char*)mFileName) );
}
// Add as observer of the xul document.
nsCOMPtr<nsIContentViewer> cv;
rv = mWebShell->GetContentViewer(getter_AddRefs(cv));
if ( cv ) {
// Up-cast.
nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(cv));
if ( docv ) {
// Get the document from the doc viewer.
nsCOMPtr<nsIDocument> doc;
rv = docv->GetDocument(*getter_AddRefs(doc));
if ( doc ) {
doc->AddObserver( this );
} else {
if (APP_DEBUG) printf("GetDocument failed, rv=0x%X\n",(int)rv);
}
} else {
if (APP_DEBUG) printf("Upcast to nsIDocumentViewer failed\n");
}
} else {
if (APP_DEBUG) printf("GetContentViewer failed, rv=0x%X\n",(int)rv);
}
return rv;
}
NS_IMETHODIMP
nsFileDownloadDialog::OnDataAvailable(nsIURL* aURL, nsIInputStream *aIStream, PRUint32 aLength) {
nsresult rv = NS_OK;
// Check for download cancelled by user.
if ( mStopped ) {
// Close the output file.
if ( mOutput ) {
mOutput->close();
}
// Close the input stream.
aIStream->Close();
} else {
// Allocate buffer space.
if ( aLength > mBufLen ) {
char *oldBuffer = mBuffer;
mBuffer = new char[ aLength ];
if ( mBuffer ) {
// Use new (bigger) buffer.
mBufLen = aLength;
// Delete old (smaller) buffer.
delete [] oldBuffer;
} else {
// Keep the one we've got.
mBuffer = oldBuffer;
}
}
// Read the data.
PRUint32 bytesRead;
rv = aIStream->Read( mBuffer, ( mBufLen > aLength ) ? aLength : mBufLen, &bytesRead );
if ( NS_SUCCEEDED(rv) ) {
// Write the data just read to the output stream.
if ( mOutput ) {
mOutput->write( mBuffer, bytesRead );
}
} else {
printf( "Error reading stream, rv=0x%X\n", (int)rv );
}
}
return rv;
}
NS_IMETHODIMP
nsFileDownloadDialog::OnStartBinding(nsIURL* aURL, const char *aContentType) {
nsresult rv = NS_OK;
return NS_OK;
}
NS_IMETHODIMP
nsFileDownloadDialog::OnProgress(nsIURL* aURL, PRUint32 aProgress, PRUint32 aProgressMax) {
nsresult rv = NS_OK;
char buf[16];
PR_snprintf( buf, sizeof buf, "%lu", aProgressMax );
setAttribute( mWebShell, "data.progress", "max", buf );
PR_snprintf( buf, sizeof buf, "%lu", aProgress );
setAttribute( mWebShell, "data.progress", "value", buf );
return NS_OK;
}
NS_IMETHODIMP
nsFileDownloadDialog::OnStatus(nsIURL* aURL, const PRUnichar* aMsg) {
nsresult rv = NS_OK;
nsString msg = aMsg;
setAttribute( mWebShell, "data.status", "value", aMsg );
return NS_OK;
}
// Utility function to close a window given a root nsIWebShell.
static void closeWindow( nsIWebShellWindow *aWebShellWindow ) {
if ( aWebShellWindow ) {
// crashes!
aWebShellWindow->Close();
}
}
NS_IMETHODIMP
nsFileDownloadDialog::OnStopBinding(nsIURL* aURL, nsresult aStatus, const PRUnichar* aMsg) {
nsresult rv = NS_OK;
// Close the output file.
if ( mOutput ) {
mOutput->close();
}
// Signal UI that download is complete.
setAttribute( mWebShell, "data.progress", "completed", "true" );
return rv;
}
// Handle attribute changing; we only care about the element "data.execute"
// which is used to signal command execution from the UI.
NS_IMETHODIMP
nsFileDownloadDialog::AttributeChanged( nsIDocument *aDocument,
nsIContent* aContent,
nsIAtom* aAttribute,
PRInt32 aHint ) {
nsresult rv = NS_OK;
// Look for data.execute command changing.
nsString id;
nsCOMPtr<nsIAtom> atomId = nsDontQueryInterface<nsIAtom>( NS_NewAtom("id") );
aContent->GetAttribute( kNameSpaceID_None, atomId, id );
if ( id == "data.execute" ) {
nsString cmd;
nsCOMPtr<nsIAtom> atomCommand = nsDontQueryInterface<nsIAtom>( NS_NewAtom("command") );
// Get requested command.
aContent->GetAttribute( kNameSpaceID_None, atomCommand, cmd );
// Reset (immediately, to prevent feedback loop).
aContent->SetAttribute( kNameSpaceID_None, atomCommand, "", PR_FALSE );
if ( cmd == "save" ) {
OnSave();
} else if ( cmd == "more" ) {
OnMore();
} else if ( cmd == "pick" ) {
OnPick();
} else if ( cmd == "start" ) {
OnStart();
} else if ( cmd == "stop" ) {
OnStop();
} else if ( cmd == "close" ) {
OnClose();
} else {
}
}
return rv;
}
// OnSave
void
nsFileDownloadDialog::OnSave() {
// Prompt user for file name.
nsCOMPtr<nsIFileWidget> fileWidget;
nsString title("Save File");
nsComponentManager::CreateInstance( kCFileWidgetCID,
nsnull,
kIFileWidgetIID,
(void**)getter_AddRefs(fileWidget) );
if (fileWidget) {
nsFileSpec fileSpec;
nsFileDlgResults result = fileWidget->PutFile( nsnull, title, fileSpec );
if ( result == nsFileDlgResults_OK || result == nsFileDlgResults_Replace ) {
// Save the stream into the specified file...
mFileName = fileSpec;
mMode = kProgress;
nsString progressXUL = "resource:/res/samples/downloadProgress.xul";
mWebShell->LoadURL( progressXUL.GetUnicode() );
// Open output file stream.
mOutput = new nsOutputFileStream( mFileName );
}
}
}
// OnMore
void
nsFileDownloadDialog::OnMore() {
printf( "nsFileDownloadDialog::OnMore not implemented yet\n" );
}
// OnPick
void
nsFileDownloadDialog::OnPick() {
printf( "nsFileDownloadDialog::OnPick not implemented yet\n" );
}
void
nsFileDownloadDialog::OnClose() {
// Close the window.
closeWindow( mWindow );
}
void
nsFileDownloadDialog::OnStart() {
if ( mMode == kProgress ) {
// Load source stream into file.
nsINetService *inet = 0;
nsresult rv = nsServiceManager::GetService( kNetServiceCID,
kINetServiceIID,
(nsISupports**)&inet );
if (NS_OK == rv) {
rv = inet->OpenStream(mUrl, this);
nsServiceManager::ReleaseService(kNetServiceCID, inet);
} else {
if ( APP_DEBUG ) { printf( "Error getting Net Service, rv=0x%X\n", (int)rv ); }
}
}
}
void
nsFileDownloadDialog::OnStop() {
// Stop the netlib xfer.
mStopped = PR_TRUE;
}
void
nsFileDownloadDialog::SetWindow( nsIWebShellWindow *aWindow ) {
mWindow = nsDontQueryInterface<nsIWebShellWindow>(aWindow);
}
NS_IMETHODIMP
nsBrowserAppCore::HandleUnknownContentType(nsIDocumentLoader* loader,
nsIURL *aURL,
@ -1365,46 +974,23 @@ nsBrowserAppCore::HandleUnknownContentType(nsIDocumentLoader* loader,
// Turn off the indicators in the chrome.
setAttribute( mWebShell, "Browser:Throbber", "busy", "false" );
// Note: The following code is broken. It should rightfully be loading
// some "unknown content type handler" component and giving it control.
// We will change this as soon as nsFileDownloadDialog is moved to a
// separate component or components.
// Get "unknown content type handler" and have it handle this.
nsIUnknownContentTypeHandler *handler;
rv = nsServiceManager::GetService( NS_IUNKNOWNCONTENTTYPEHANDLER_PROGID,
nsIUnknownContentTypeHandler::GetIID(),
(nsISupports**)&handler );
// Get app shell service.
nsIAppShellService *appShell;
rv = nsServiceManager::GetService(kAppShellServiceCID,
kIAppShellServiceIID,
(nsISupports**)&appShell);
if ( NS_SUCCEEDED( rv ) ) {
/* Have handler take care of this. */
rv = handler->HandleUnknownContentType( aURL, aContentType, loader );
if ( NS_SUCCEEDED(rv) ) {
// Open "Save to disk" dialog.
nsIWebShellWindow *newWindow;
// Make url for dialog xul.
nsIURL *url;
rv = NS_NewURL( &url, "resource:/res/samples/unknownContent.xul" );
if ( NS_SUCCEEDED(rv) ) {
// Create "save to disk" nsIXULCallbacks...
nsFileDownloadDialog *dialog = new nsFileDownloadDialog( aURL, aContentType );
rv = appShell->CreateTopLevelWindow( nsnull,
url,
PR_TRUE,
newWindow,
nsnull,
dialog,
425,
200 );
// Give find dialog the window pointer (if it worked).
if ( NS_SUCCEEDED(rv) ) {
dialog->SetWindow( newWindow );
}
NS_RELEASE(url);
}
nsServiceManager::ReleaseService(kAppShellServiceCID, appShell);
// Release the unknown content type handler service object.
nsServiceManager::ReleaseService( NS_IUNKNOWNCONTENTTYPEHANDLER_PROGID, handler );
} else {
#ifdef NS_DEBUG
printf( "%s %d: GetService failed for unknown content type handler, rv=0x%08X\n",
__FILE__, (int)__LINE__, (int)rv );
#endif
}
return rv;
@ -1450,59 +1036,6 @@ nsBrowserAppCore::OnEndURLLoad(nsIDocumentLoader* loader,
return NS_OK;
}
#if 0
NS_IMETHODIMP
nsBrowserAppCore::BeginLoadURL(nsIWebShell* aShell, const PRUnichar* aURL)
{
setAttribute( mWebShell, "Browser:Throbber", "busy", "true" );
return NS_OK;
}
NS_IMETHODIMP
nsBrowserAppCore::ProgressLoadURL(nsIWebShell* aShell, const PRUnichar* aURL,
PRInt32 aProgress, PRInt32 aProgressMax)
{
return rv;
}
NS_IMETHODIMP
nsBrowserAppCore::EndLoadURL(nsIWebShell* aWebShell, const PRUnichar* aURL,
PRInt32 aStatus)
{
// Update global history.
NS_ASSERTION(mGHistory != nsnull, "history not initialized");
if (mGHistory) {
nsresult rv;
nsAutoString url(aURL);
char* urlSpec = url.ToNewCString();
do {
if (NS_FAILED(rv = mGHistory->AddPage(urlSpec, /* XXX referrer? */ nsnull, PR_Now()))) {
NS_ERROR("unable to add page to history");
break;
}
const PRUnichar* title;
if (NS_FAILED(rv = aWebShell->GetTitle(&title))) {
NS_ERROR("unable to get doc title");
break;
}
if (NS_FAILED(rv = mGHistory->SetPageTitle(urlSpec, title))) {
NS_ERROR("unable to set doc title");
break;
}
} while (0);
delete[] urlSpec;
}
setAttribute( mWebShell, "Browser:Throbber", "busy", "false" );
return NS_OK;
}
#endif /* 0 */
NS_IMETHODIMP
nsBrowserAppCore::NewWindow()
{
@ -1590,7 +1123,6 @@ nsBrowserAppCore::OpenWindow()
nsString title("Open File");
if (NS_OK == nsComponentManager::CreateInstance(kCFileWidgetCID, nsnull, kIFileWidgetIID, (void**)&fileWidget)) {
nsString titles[] = {"All Readable Files", "HTML Files",
"XML Files", "Image Files", "All Files"};
nsString filters[] = {"*.htm; *.html; *.xml; *.gif; *.jpg; *.jpeg; *.png",
@ -1600,7 +1132,6 @@ nsBrowserAppCore::OpenWindow()
"*.*"};
fileWidget->SetFilterList(5, titles, filters);
nsFileSpec fileSpec;
if (fileWidget->GetFile(nsnull, title, fileSpec) == nsFileDlgResults_OK) {
nsFileURL fileURL(fileSpec);
@ -1689,44 +1220,12 @@ nsBrowserAppCore::Exit()
}
void
nsBrowserAppCore::InitializeSearch() {
nsBrowserAppCore::InitializeSearch( nsIFindComponent *finder ) {
nsresult rv = NS_OK;
// First, get find component (if we haven't done so already).
if ( !mFindComponent ) {
// Ultimately, should be something like appShell->GetComponent().
rv = nsComponentManager::CreateInstance( NS_IFINDCOMPONENT_PROGID,
0,
nsIFindComponent::GetIID(),
(void**)&mFindComponent );
if ( NS_SUCCEEDED( rv ) ) {
// Initialize the find component.
nsIAppShellService *appShell = 0;
rv = nsServiceManager::GetService( kAppShellServiceCID,
nsIAppShellService::GetIID(),
(nsISupports**)&appShell );
if ( NS_SUCCEEDED( rv ) ) {
// Initialize the find component.
mFindComponent->Initialize( appShell, 0 );
// Release the app shell.
nsServiceManager::ReleaseService( kAppShellServiceCID, appShell );
} else {
#ifdef NS_DEBUG
printf( "nsBrowserAppCore::InitializeSearch failed, GetService rv=0x%X\n", (int)rv );
#endif
// Couldn't initialize it, so release it.
mFindComponent->Release();
}
} else {
#ifdef NS_DEBUG
printf( "nsBrowserAppCore::InitializeSearch failed, CreateInstace rv=0x%X\n", (int)rv );
#endif
}
}
if ( NS_SUCCEEDED( rv ) && !mSearchContext ) {
if ( finder && !mSearchContext ) {
// Create the search context for this browser window.
nsresult rv = mFindComponent->CreateContext( mContentAreaWebShell, &mSearchContext );
rv = finder->CreateContext( mContentAreaWebShell, &mSearchContext );
if ( NS_FAILED( rv ) ) {
#ifdef NS_DEBUG
printf( "%s %d CreateContext failed, rv=0x%X\n",
@ -1736,32 +1235,31 @@ nsBrowserAppCore::InitializeSearch() {
}
}
//Obsolete, to be removed.
void
nsBrowserAppCore::ResetSearchContext() {
// Test if we've created the search context yet.
if ( mFindComponent && mSearchContext ) {
// OK, reset it.
nsresult rv = mFindComponent->ResetContext( mSearchContext, mContentAreaWebShell );
if ( NS_FAILED( rv ) ) {
#ifdef NS_DEBUG
printf( "%s %d ResetContext failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
#endif
}
}
}
NS_IMETHODIMP
nsBrowserAppCore::Find() {
nsresult rv = NS_OK;
// Make sure we've initialized searching for this document.
InitializeSearch();
// Get find component.
nsIFindComponent *finder;
rv = nsServiceManager::GetService( NS_IFINDCOMPONENT_PROGID,
nsIFindComponent::GetIID(),
(nsISupports**)&finder );
if ( NS_SUCCEEDED( rv ) ) {
// Make sure we've initialized searching for this document.
InitializeSearch( finder );
// Perform find via find component.
if ( mFindComponent && mSearchContext ) {
rv = mFindComponent->Find( mSearchContext );
// Perform find via find component.
if ( finder && mSearchContext ) {
rv = finder->Find( mSearchContext );
}
// Release the service.
nsServiceManager::ReleaseService( NS_IFINDCOMPONENT_PROGID, finder );
} else {
#ifdef NS_DEBUG
printf( "%s %d: GetService failed for find component, rv=0x08%X\n",
__FILE__, (int)__LINE__, (int)rv );
#endif
}
return rv;
@ -1771,12 +1269,27 @@ NS_IMETHODIMP
nsBrowserAppCore::FindNext() {
nsresult rv = NS_OK;
// Make sure we've initialized searching for this document.
InitializeSearch();
// Get find component.
nsIFindComponent *finder;
rv = nsServiceManager::GetService( NS_IFINDCOMPONENT_PROGID,
nsIFindComponent::GetIID(),
(nsISupports**)&finder );
if ( NS_SUCCEEDED( rv ) ) {
// Make sure we've initialized searching for this document.
InitializeSearch( finder );
// Perform find next via find component.
if ( mFindComponent && mSearchContext ) {
rv = mFindComponent->FindNext( mSearchContext );
// Perform find via find component.
if ( finder && mSearchContext ) {
rv = finder->FindNext( mSearchContext );
}
// Release the service.
nsServiceManager::ReleaseService( NS_IFINDCOMPONENT_PROGID, finder );
} else {
#ifdef NS_DEBUG
printf( "%s %d: GetService failed for find component, rv=0x08%X\n",
__FILE__, (int)__LINE__, (int)rv );
#endif
}
return rv;
@ -1821,53 +1334,6 @@ nsBrowserAppCore::DoDialog()
return rv;
}
#if 0
NS_IMETHODIMP
nsBrowserAppCore::OnStartBinding(nsIURL* aURL, const char *aContentType)
{
nsresult rv = NS_OK;
const char *urlString = 0;
aURL->GetSpec( &urlString );
if ( urlString ) {
setAttribute( mWebShell, "Browser:OnStartBinding", "content-type", aContentType );
setAttribute( mWebShell, "Browser:OnStartBinding", "url", urlString );
}
return rv;
}
NS_IMETHODIMP
nsBrowserAppCore::OnProgress(nsIURL* aURL, PRUint32 aProgress, PRUint32 aProgressMax)
{
return NS_OK;
}
NS_IMETHODIMP
nsBrowserAppCore::OnStatus(nsIURL* aURL, const PRUnichar* aMsg)
{
nsresult rv = setAttribute( mWebShell, "Browser:Status", "text", aMsg );
return rv;
}
NS_IMETHODIMP
nsBrowserAppCore::OnStopBinding(nsIURL* aURL, nsresult aStatus, const PRUnichar* aMsg)
{
nsresult rv = NS_OK;
const char *urlString = 0;
aURL->GetSpec( &urlString );
if ( urlString ) {
char status[256];
PR_snprintf( status, sizeof status, "0x%08X", (int) aStatus );
setAttribute( mWebShell, "Browser:OnStopBinding", "status", status );
setAttribute( mWebShell, "Browser:OnStopBinding", "text", aMsg );
setAttribute( mWebShell, "Browser:OnStopBinding", "url", urlString );
}
return rv;
}
#endif /* 0 */
//----------------------------------------------------------------------
NS_IMETHODIMP_(void)

View File

@ -125,8 +125,7 @@ class nsBrowserAppCore : public nsBaseAppCore,
NS_IMETHOD DoDialog();
NS_IMETHOD ExecuteScript(nsIScriptContext * aContext, const nsString& aScript);
void SetButtonImage(nsIDOMNode * aParentNode, PRInt32 aBtnNum, const nsString &aResName);
void InitializeSearch();
void ResetSearchContext();
void InitializeSearch(nsIFindComponent*);
nsIScriptContext *mToolbarScriptContext;
nsIScriptContext *mContentScriptContext;
@ -140,7 +139,6 @@ class nsBrowserAppCore : public nsBaseAppCore,
nsIGlobalHistory* mGHistory;
static nsIFindComponent * mFindComponent;
nsISupports * mSearchContext;
};

View File

@ -31,6 +31,7 @@ class nsIWebShellWindow;
class nsString;
class nsIStreamObserver;
class nsIXULWindowCallbacks;
class nsICmdLineService;
// e5e5af70-8a38-11d2-9938-0080c7cb1080
#define NS_IAPPSHELL_SERVICE_IID \
@ -43,7 +44,7 @@ class nsIAppShellService : public nsISupports
public:
static const nsIID& GetIID() { static nsIID iid = NS_IAPPSHELL_SERVICE_IID; return iid; }
NS_IMETHOD Initialize(void) = 0;
NS_IMETHOD Initialize(nsICmdLineService * aCmdLineService) = 0;
NS_IMETHOD Run(void) = 0;
NS_IMETHOD Shutdown(void) = 0;

View File

@ -61,7 +61,9 @@ LINCS=-I$(PUBLIC)\raptor \
-I$(PUBLIC)\appcores \
-I$(PUBLIC)\netlib \
-I$(PUBLIC)\rdf \
-I$(PUBLIC)\pics
-I$(PUBLIC)\pics \
-I$(PUBLIC)\xpfe\components \
$(NULL)
MAKE_OBJ_TYPE = DLL
DLLNAME = nsappshell

View File

@ -33,6 +33,14 @@
#include "nsWebShellWindow.h"
#include "nsIGlobalHistory.h"
#include "nsIAppShellComponent.h"
#include "nsIRegistry.h"
#include "nsIEnumerator.h"
#include "nsICmdLineService.h"
#ifdef NS_DEBUG
#include "prprf.h"
#endif
/* For Javascript Namespace Access */
#include "nsDOMCID.h"
#include "nsIScriptNameSetRegistry.h"
@ -75,7 +83,7 @@ public:
NS_DECL_ISUPPORTS
NS_IMETHOD Initialize(void);
NS_IMETHOD Initialize(nsICmdLineService*aCmdLineService);
NS_IMETHOD Run(void);
NS_IMETHOD Shutdown(void);
NS_IMETHOD CreateTopLevelWindow(nsIWebShellWindow * aParent,
@ -103,8 +111,13 @@ public:
protected:
virtual ~nsAppShellService();
void InitializeComponent( const nsCID &aComponentCID );
void ShutdownComponent( const nsCID &aComponentCID );
void EnumerateComponents( void (nsAppShellService::*function)(const nsCID&) );
nsIAppShell* mAppShell;
nsISupportsArray* mWindowList;
nsICmdLineService* mCmdLineService;
};
@ -114,12 +127,14 @@ nsAppShellService::nsAppShellService()
mAppShell = nsnull;
mWindowList = nsnull;
mCmdLineService = nsnull;
}
nsAppShellService::~nsAppShellService()
{
NS_IF_RELEASE(mAppShell);
NS_IF_RELEASE(mWindowList);
NS_IF_RELEASE(mCmdLineService);
}
@ -130,7 +145,7 @@ NS_IMPL_ISUPPORTS(nsAppShellService, kIAppShellServiceIID);
NS_IMETHODIMP
nsAppShellService::Initialize(void)
nsAppShellService::Initialize( nsICmdLineService *aCmdLineService )
{
nsresult rv;
#ifdef XP_PC
@ -140,6 +155,10 @@ nsAppShellService::Initialize(void)
#ifdef MOZ_FULLCIRCLE
FCInitialize();
#endif
// Remember cmd line service.
mCmdLineService = aCmdLineService;
NS_IF_ADDREF( mCmdLineService );
// Create the Event Queue for the UI thread...
nsIEventQueueService* eventQService;
rv = nsServiceManager::GetService(kEventQueueServiceCID,
@ -197,10 +216,174 @@ nsAppShellService::Initialize(void)
rv = mAppShell->Create(0, nsnull);
if (NS_FAILED(rv)) {
goto done;
}
// Initialize each registered component.
EnumerateComponents( InitializeComponent );
done:
return rv;
}
// Apply function (Initialize/Shutdown) to each app shell component.
void
nsAppShellService::EnumerateComponents( void (nsAppShellService::*function)( const nsCID& ) ) {
nsresult rv;
nsIRegistry *registry = 0;
nsIRegistry::Key key;
nsIEnumerator *components = 0;
const char *failed = "GetService";
if ( NS_SUCCEEDED( ( rv = nsServiceManager::GetService( NS_REGISTRY_PROGID,
nsIRegistry::GetIID(),
(nsISupports**)&registry ) ) )
&&
( failed = "Open" )
&&
NS_SUCCEEDED( ( rv = registry->Open() ) )
&&
( failed = "GetSubtree" )
&&
NS_SUCCEEDED( ( rv = registry->GetSubtree( nsIRegistry::Common,
NS_IAPPSHELLCOMPONENT_KEY,
&key ) ) )
&&
( failed = "EnumerateSubtrees" )
&&
NS_SUCCEEDED( ( rv = registry->EnumerateSubtrees( key,
&components ) ) )
&&
( failed = "First" )
&&
NS_SUCCEEDED( ( rv = components->First() ) ) ) {
// Enumerate all subtrees
while ( NS_SUCCEEDED( rv ) && !components->IsDone() ) {
nsISupports *base;
rv = components->CurrentItem( &base );
if ( NS_SUCCEEDED( rv ) ) {
// Get specific interface.
nsIRegistryNode *node;
nsIID nodeIID = NS_IREGISTRYNODE_IID;
rv = base->QueryInterface( nodeIID, (void**)&node );
// Test that result.
if ( NS_SUCCEEDED( rv ) ) {
// Get node name.
char *name;
rv = node->GetName( &name );
if ( NS_SUCCEEDED( rv ) ) {
// If this is a CID of a component; apply function to it.
nsCID cid;
if ( cid.Parse( name ) ) {
(this->*function)( cid );
} else {
// Not a valid CID, ignore it.
}
} else {
// Unable to get subkey name, ignore it.
}
// Release the node.
NS_RELEASE( node );
} else {
// Unable to convert item to registry node, ignore it.
}
// Release the current (generic) item.
NS_RELEASE( base );
} else {
// Unable to get current item, ignore it.
}
// Go on to next component, if this fails, we quit.
rv = components->Next();
}
} else {
// Unable to set up for subkey enumeration.
#ifdef NS_DEBUG
PR_fprintf( PR_STDOUT, "Unable to enumerator app shell components, %s rv=0x%08X\n",
failed, (int)rv );
#endif
}
// Clean up.
if ( registry ) {
// Registry was accessed, close it.
registry->Close();
// Release enumerator (if necessary).
NS_IF_RELEASE( components );
// Release nsIRegistry service.
nsServiceManager::ReleaseService( NS_REGISTRY_PROGID, registry );
}
return;
}
void
nsAppShellService::InitializeComponent( const nsCID &aComponentCID ) {
// Attempt to create instance of the component.
nsIAppShellComponent *component;
nsresult rv = nsComponentManager::CreateInstance( aComponentCID,
0,
nsIAppShellComponent::GetIID(),
(void**)&component );
if ( NS_SUCCEEDED( rv ) ) {
// Then tell it to initialize (it may RegisterService itself).
rv = component->Initialize( this, mCmdLineService );
#ifdef NS_DEBUG
char *name = aComponentCID.ToString();
PR_fprintf( PR_STDOUT, "Initialized app shell component %s, rv=0x%08X\n",
name, (int)rv );
delete [] name;
#endif
// Release it (will live on if it registered itself as service).
component->Release();
} else {
// Error creating component.
#ifdef NS_DEBUG
char *name = aComponentCID.ToString();
PR_fprintf( PR_STDOUT, "Error creating app shell component %s, rv=0x%08X\n",
name, (int)rv );
delete [] name;
#endif
}
return;
}
void
nsAppShellService::ShutdownComponent( const nsCID &aComponentCID ) {
// Attempt to create instance of the component (must be a service).
nsIAppShellComponent *component;
nsresult rv = nsServiceManager::GetService( aComponentCID,
nsIAppShellComponent::GetIID(),
(nsISupports**)&component );
if ( NS_SUCCEEDED( rv ) ) {
// Instance accessed, tell it to shutdown.
rv = component->Shutdown();
#ifdef NS_DEBUG
char *name = aComponentCID.ToString();
PR_fprintf( PR_STDOUT, "Shut down app shell component %s, rv=0x%08X\n",
name, (int)rv );
delete [] name;
#endif
// Release the service.
nsServiceManager::ReleaseService( aComponentCID, component );
} else {
// Error getting component service (perhaps due to that component not being
// a service).
#ifdef NS_DEBUG
char *name = aComponentCID.ToString();
PR_fprintf( PR_STDOUT, "Unable to shut down app shell component %s, rv=0x%08X\n",
name, (int)rv );
delete [] name;
#endif
}
return;
}
NS_IMETHODIMP
nsAppShellService::Run(void)
@ -213,6 +396,9 @@ nsAppShellService::Shutdown(void)
{
#if 1
// Shutdown all components.
EnumerateComponents( ShutdownComponent );
mAppShell->Exit();
#else
while (mWindowList->Count() > 0) {

View File

@ -341,7 +341,7 @@ int main(int argc, char* argv[])
/*
* Initialize the Shell...
*/
rv = appShell->Initialize();
rv = appShell->Initialize( cmdLineArgs );
if (NS_FAILED(rv)) {
goto done;
}

View File

@ -92,9 +92,23 @@ public:
// should not be registered with the Service Manager
// when Initialize-d.
virtual PRBool Is_Service() { return PR_TRUE; }
static nsresult SetServiceManager( nsISupports *aServiceMgr ) {
nsresult rv = NS_OK;
// Remember service manager first time we see it.
if ( !mServiceMgr ) {
// Convert to proper interface.
rv = aServiceMgr->QueryInterface( nsIServiceManager::GetIID(),
(void**)&mServiceMgr );
}
return rv;
}
static nsIServiceManager *mServiceMgr;
static nsIAppShellService *mAppShell;
static nsICmdLineService *mCmdLine;
#ifdef NS_DEBUG
nsAppShellComponentImpl();
virtual ~nsAppShellComponentImpl();
#endif
}; // nsAppShellComponent
#define NS_DEFINE_COMPONENT_GLOBALS() \
@ -102,6 +116,20 @@ nsIServiceManager *nsAppShellComponentImpl::mServiceMgr = 0; \
nsIAppShellService *nsAppShellComponentImpl::mAppShell = 0; \
nsICmdLineService *nsAppShellComponentImpl::mCmdLine = 0;
// Macros to define ctor/dtor for implementation class.
// These differ in debug vs. non-debug situations.
#ifdef NS_DEBUG
#define NS_IMPL_IAPPSHELLCOMPONENTIMPL_CTORDTOR(className) \
nsAppShellComponentImpl::nsAppShellComponentImpl() { \
DEBUG_PRINTF( PR_STDOUT, #className " component created\n" ); \
} \
nsAppShellComponentImpl::~nsAppShellComponentImpl() { \
DEBUG_PRINTF( PR_STDOUT, #className " component destroyed\n" ); \
}
#else
#define NS_IMPL_IAPPSHELLCOMPONENTIMPL_CTORDTOR(className)
#endif
#define NS_IMPL_IAPPSHELLCOMPONENT( className, interfaceName, progId ) \
/* Define instance counter implementation stuff. */\
NS_DEFINE_MODULE_INSTANCE_COUNTER() \
@ -235,8 +263,7 @@ extern "C" NS_EXPORT nsresult \
NSRegisterSelf( nsISupports* aServiceMgr, const char* path ) { \
nsresult rv = NS_OK; \
/* Remember service manager. */\
rv = aServiceMgr->QueryInterface( nsIServiceManager::GetIID(), \
(void**)&className::mServiceMgr ); \
rv = className::SetServiceManager( aServiceMgr ); \
if ( NS_SUCCEEDED( rv ) ) { \
/* Get the component manager service. */\
nsCID cid = NS_COMPONENTMANAGER_CID; \
@ -291,7 +318,7 @@ NSRegisterSelf( nsISupports* aServiceMgr, const char* path ) { \
DEBUG_PRINTF( PR_STDOUT, #className " registration failed, GetService rv=0x%X\n", (int)rv ); \
} \
} else { \
DEBUG_PRINTF( PR_STDOUT, #className " registration failed, QueryInterface rv=0x%X\n", (int)rv ); \
DEBUG_PRINTF( PR_STDOUT, #className " registration failed, bad service mgr, rv=0x%X\n", (int)rv ); \
} \
return rv; \
} \
@ -299,14 +326,14 @@ NSRegisterSelf( nsISupports* aServiceMgr, const char* path ) { \
extern "C" NS_EXPORT nsresult \
NSUnregisterSelf( nsISupports* aServiceMgr, const char* path ) { \
nsresult rv = NS_OK; \
nsCOMPtr<nsIServiceManager> serviceMgr( do_QueryInterface( aServiceMgr, &rv ) ); \
rv = className::SetServiceManager( aServiceMgr ); \
if ( NS_SUCCEEDED( rv ) ) { \
/* Get the component manager service. */\
nsCID cid = NS_COMPONENTMANAGER_CID; \
nsIComponentManager *componentMgr = 0; \
rv = serviceMgr->GetService( cid, \
nsIComponentManager::GetIID(), \
(nsISupports**)&componentMgr ); \
rv = className::mServiceMgr->GetService( cid, \
nsIComponentManager::GetIID(), \
(nsISupports**)&componentMgr ); \
if ( NS_SUCCEEDED( rv ) ) { \
/* Unregister our component. */\
rv = componentMgr->UnregisterComponent( className::GetCID(), path ); \
@ -316,44 +343,49 @@ NSUnregisterSelf( nsISupports* aServiceMgr, const char* path ) { \
DEBUG_PRINTF( PR_STDOUT, #className " unregistration failed, UnregisterComponent rv=0x%X\n", (int)rv ); \
} \
/* Release the component manager service. */\
serviceMgr->ReleaseService( cid, componentMgr ); \
className::mServiceMgr->ReleaseService( cid, componentMgr ); \
} else { \
DEBUG_PRINTF( PR_STDOUT, #className, " unregistration failed, GetService rv=0x%X\n", (int)rv ); \
} \
} else { \
DEBUG_PRINTF( PR_STDOUT, #className " unregistration failed, QueryInterface rv=0x%X\n", (int)rv ); \
DEBUG_PRINTF( PR_STDOUT, #className " unregistration failed, bad service mgr, rv=0x%X\n", (int)rv ); \
} \
return rv; \
} \
/* NSGetFactory implementation */\
extern "C" NS_EXPORT nsresult \
NSGetFactory( nsISupports *aServMgr, \
NSGetFactory( nsISupports *aServiceMgr, \
const nsCID &aClass, \
const char *aClassName, \
const char *aProgID, \
nsIFactory* *aFactory ) { \
nsresult rv = NS_OK; \
if ( aFactory ) { \
className##Factory *factory = new className##Factory(); \
if ( factory ) { \
rv = factory->QueryInterface( nsIFactory::GetIID(), (void**)aFactory ); \
if ( NS_FAILED( rv ) ) { \
DEBUG_PRINTF( PR_STDOUT, #className " NSGetFactory failed, QueryInterface rv=0x%X\n", (int)rv ); \
/* Delete this bogus factory. */\
delete factory; \
rv = className::SetServiceManager( aServiceMgr ); \
if ( NS_SUCCEEDED( rv ) ) { \
if ( aFactory ) { \
className##Factory *factory = new className##Factory(); \
if ( factory ) { \
rv = factory->QueryInterface( nsIFactory::GetIID(), (void**)aFactory ); \
if ( NS_FAILED( rv ) ) { \
DEBUG_PRINTF( PR_STDOUT, #className " NSGetFactory failed, QueryInterface rv=0x%X\n", (int)rv ); \
/* Delete this bogus factory. */\
delete factory; \
} \
} else { \
rv = NS_ERROR_OUT_OF_MEMORY; \
} \
} else { \
rv = NS_ERROR_OUT_OF_MEMORY; \
rv = NS_ERROR_NULL_POINTER; \
} \
} else { \
rv = NS_ERROR_NULL_POINTER; \
} \
return rv; \
} \
/* NSCanUnload implementation */\
extern "C" NS_EXPORT PRBool \
NSCanUnload( nsISupports* aServiceMgr ) { \
className::SetServiceManager( aServiceMgr ); \
return nsInstanceCounter::CanUnload(); \
}
} \
NS_IMPL_IAPPSHELLCOMPONENTIMPL_CTORDTOR( className ) \
#endif

View File

@ -77,6 +77,13 @@ nsDownloadProgressDialog::nsDownloadProgressDialog( nsIURL *aURL,
NS_INIT_REFCNT();
}
// dtor
nsDownloadProgressDialog::~nsDownloadProgressDialog() {
// Delete dynamically allocated members (file and buffer).
delete mOutput;
delete [] mBuffer;
}
// Open the dialog.
NS_IMETHODIMP
nsDownloadProgressDialog::Show() {

View File

@ -107,7 +107,7 @@ public:
// nsDownloadProgressDialog stuff
nsDownloadProgressDialog( nsIURL *anInputURL, const nsFileSpec &anOutputFileName );
~nsDownloadProgressDialog() { delete mOutput; delete [] mBuffer; }
~nsDownloadProgressDialog();
NS_IMETHOD Show();
protected: