зеркало из https://github.com/mozilla/gecko-dev.git
Move the destruction from the destructor into its |Destroy| method so that the document viewer is not prevented from being deleted by the cycles it would have broken in its destructor. (This has become necessary since the document viewer is being used from JS/XBL.) Use a null |mDocument| to record the destroyed state. r=disttsc@bart.nl sr=waterson@netscape.com b=61821
This commit is contained in:
Родитель
69b99f80c6
Коммит
0195b11a4d
|
@ -376,7 +376,7 @@ NS_NewDocumentViewer(nsIDocumentViewer** aResult)
|
||||||
// Note: operator new zeros our memory
|
// Note: operator new zeros our memory
|
||||||
DocumentViewerImpl::DocumentViewerImpl()
|
DocumentViewerImpl::DocumentViewerImpl()
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_ISUPPORTS();
|
||||||
mEnableRendering = PR_TRUE;
|
mEnableRendering = PR_TRUE;
|
||||||
mFilePointer = nsnull;
|
mFilePointer = nsnull;
|
||||||
mPrintListener = nsnull;
|
mPrintListener = nsnull;
|
||||||
|
@ -385,7 +385,7 @@ DocumentViewerImpl::DocumentViewerImpl()
|
||||||
DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext)
|
DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext)
|
||||||
: mPresContext(dont_QueryInterface(aPresContext))
|
: mPresContext(dont_QueryInterface(aPresContext))
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_ISUPPORTS();
|
||||||
mHintCharsetSource = kCharsetUninitialized;
|
mHintCharsetSource = kCharsetUninitialized;
|
||||||
mAllowPlugins = PR_TRUE;
|
mAllowPlugins = PR_TRUE;
|
||||||
mEnableRendering = PR_TRUE;
|
mEnableRendering = PR_TRUE;
|
||||||
|
@ -393,100 +393,24 @@ DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ISupports implementation...
|
NS_IMPL_ISUPPORTS5(DocumentViewerImpl,
|
||||||
NS_IMPL_ADDREF(DocumentViewerImpl)
|
nsIContentViewer,
|
||||||
NS_IMPL_RELEASE(DocumentViewerImpl)
|
nsIDocumentViewer,
|
||||||
|
nsIMarkupDocumentViewer,
|
||||||
nsresult
|
nsIContentViewerFile,
|
||||||
DocumentViewerImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
nsIContentViewerEdit)
|
||||||
{
|
|
||||||
if (NULL == aInstancePtr) {
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIContentViewer))) {
|
|
||||||
nsIContentViewer* tmp = this;
|
|
||||||
*aInstancePtr = (void*)tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIDocumentViewer))) {
|
|
||||||
nsIDocumentViewer* tmp = this;
|
|
||||||
*aInstancePtr = (void*) tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIMarkupDocumentViewer))) {
|
|
||||||
nsIMarkupDocumentViewer* tmp = this;
|
|
||||||
*aInstancePtr = (void*) tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIContentViewerFile))) {
|
|
||||||
nsIContentViewerFile* tmp = this;
|
|
||||||
*aInstancePtr = (void*) tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIContentViewerEdit))) {
|
|
||||||
nsIContentViewerEdit* tmp = this;
|
|
||||||
*aInstancePtr = (void*) tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
|
||||||
nsIContentViewer* tmp1 = this;
|
|
||||||
nsISupports* tmp2 = tmp1;
|
|
||||||
*aInstancePtr = (void*) tmp2;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
return NS_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DocumentViewerImpl::~DocumentViewerImpl()
|
DocumentViewerImpl::~DocumentViewerImpl()
|
||||||
{
|
{
|
||||||
nsresult rv;
|
NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Destroy");
|
||||||
|
if (mDocument)
|
||||||
if (mDocument) {
|
Destroy();
|
||||||
// Break global object circular reference on the document created
|
|
||||||
// in the DocViewer Init
|
|
||||||
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
||||||
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
||||||
if (globalObject) {
|
|
||||||
globalObject->SetNewDocument(nsnull);
|
|
||||||
}
|
|
||||||
// out of band cleanup of webshell
|
|
||||||
mDocument->SetScriptGlobalObject(nsnull);
|
|
||||||
if (mFocusListener) {
|
|
||||||
// get the DOM event receiver
|
|
||||||
nsCOMPtr<nsIDOMEventReceiver> erP;
|
|
||||||
rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP));
|
|
||||||
if(NS_SUCCEEDED(rv) && erP)
|
|
||||||
erP->RemoveEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// clear weak references before we go away
|
||||||
if (mPresContext) {
|
if (mPresContext) {
|
||||||
mPresContext->SetContainer(nsnull);
|
mPresContext->SetContainer(nsnull);
|
||||||
mPresContext->SetLinkHandler(nsnull);
|
mPresContext->SetLinkHandler(nsnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDeviceContext)
|
|
||||||
mDeviceContext->FlushFontCache();
|
|
||||||
|
|
||||||
if (mPresShell) {
|
|
||||||
// Break circular reference (or something)
|
|
||||||
mPresShell->EndObservingDocument();
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
rv = GetDocumentSelection(getter_AddRefs(selection));
|
|
||||||
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(selection));
|
|
||||||
if (NS_FAILED(rv) || !selPrivate)
|
|
||||||
return;
|
|
||||||
if (mSelectionListener)
|
|
||||||
selPrivate->RemoveSelectionListener(mSelectionListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -535,10 +459,7 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget,
|
||||||
const nsRect& aBounds)
|
const nsRect& aBounds)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER);
|
||||||
if (!mDocument) {
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDeviceContext = dont_QueryInterface(aDeviceContext);
|
mDeviceContext = dont_QueryInterface(aDeviceContext);
|
||||||
|
|
||||||
|
@ -689,13 +610,12 @@ NS_IMETHODIMP
|
||||||
DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||||
|
|
||||||
// First, get the script global object from the document...
|
// First, get the script global object from the document...
|
||||||
if (mDocument) {
|
rv = mDocument->GetScriptGlobalObject(getter_AddRefs(global));
|
||||||
rv = mDocument->GetScriptGlobalObject(getter_AddRefs(global));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fail if no ScriptGlobalObject is available...
|
// Fail if no ScriptGlobalObject is available...
|
||||||
NS_ASSERTION(global, "nsIScriptGlobalObject not set for document!");
|
NS_ASSERTION(global, "nsIScriptGlobalObject not set for document!");
|
||||||
|
@ -718,14 +638,56 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Destroy(void)
|
DocumentViewerImpl::Destroy()
|
||||||
{
|
{
|
||||||
return NS_ERROR_FAILURE;
|
// All callers are supposed to call destroy to break circular
|
||||||
|
// references. If we do this stuff in the destructor, the
|
||||||
|
// destructor might never be called (especially if we're being
|
||||||
|
// used from JS.
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
if (mDocument) {
|
||||||
|
// Break global object circular reference on the document created
|
||||||
|
// in the DocViewer Init
|
||||||
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
||||||
|
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
||||||
|
if (globalObject) {
|
||||||
|
globalObject->SetNewDocument(nsnull);
|
||||||
|
}
|
||||||
|
// out of band cleanup of webshell
|
||||||
|
mDocument->SetScriptGlobalObject(nsnull);
|
||||||
|
if (mFocusListener) {
|
||||||
|
// get the DOM event receiver
|
||||||
|
nsCOMPtr<nsIDOMEventReceiver> erP;
|
||||||
|
rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP));
|
||||||
|
if(NS_SUCCEEDED(rv) && erP)
|
||||||
|
erP->RemoveEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDeviceContext)
|
||||||
|
mDeviceContext->FlushFontCache();
|
||||||
|
|
||||||
|
if (mPresShell) {
|
||||||
|
// Break circular reference (or something)
|
||||||
|
mPresShell->EndObservingDocument();
|
||||||
|
nsCOMPtr<nsISelection> selection;
|
||||||
|
rv = GetDocumentSelection(getter_AddRefs(selection));
|
||||||
|
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(selection));
|
||||||
|
if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener)
|
||||||
|
selPrivate->RemoveSelectionListener(mSelectionListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
mDocument = nsnull;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Stop(void)
|
DocumentViewerImpl::Stop(void)
|
||||||
{
|
{
|
||||||
|
NS_ASSERTION(mDocument, "Stop called too early or too late");
|
||||||
if (mDocument) {
|
if (mDocument) {
|
||||||
mDocument->StopDocumentLoad();
|
mDocument->StopDocumentLoad();
|
||||||
}
|
}
|
||||||
|
@ -740,6 +702,7 @@ DocumentViewerImpl::Stop(void)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::GetDOMDocument(nsIDOMDocument **aResult)
|
DocumentViewerImpl::GetDOMDocument(nsIDOMDocument **aResult)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
return CallQueryInterface(mDocument.get(), aResult);
|
return CallQueryInterface(mDocument.get(), aResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,6 +809,7 @@ DocumentViewerImpl::GetPresContext(nsIPresContext*& aResult)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::GetBounds(nsRect& aResult)
|
DocumentViewerImpl::GetBounds(nsRect& aResult)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
mWindow->GetBounds(aResult);
|
mWindow->GetBounds(aResult);
|
||||||
|
@ -859,6 +823,7 @@ DocumentViewerImpl::GetBounds(nsRect& aResult)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::SetBounds(const nsRect& aBounds)
|
DocumentViewerImpl::SetBounds(const nsRect& aBounds)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
// Don't have the widget repaint. Layout will generate repaint requests
|
// Don't have the widget repaint. Layout will generate repaint requests
|
||||||
|
@ -872,6 +837,7 @@ DocumentViewerImpl::SetBounds(const nsRect& aBounds)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Move(PRInt32 aX, PRInt32 aY)
|
DocumentViewerImpl::Move(PRInt32 aX, PRInt32 aY)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
mWindow->Move(aX, aY);
|
mWindow->Move(aX, aY);
|
||||||
|
@ -882,6 +848,7 @@ DocumentViewerImpl::Move(PRInt32 aX, PRInt32 aY)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Show(void)
|
DocumentViewerImpl::Show(void)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
mWindow->Show(PR_TRUE);
|
mWindow->Show(PR_TRUE);
|
||||||
|
@ -892,6 +859,7 @@ DocumentViewerImpl::Show(void)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Hide(void)
|
DocumentViewerImpl::Hide(void)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
mWindow->Show(PR_FALSE);
|
mWindow->Show(PR_FALSE);
|
||||||
|
@ -1812,6 +1780,7 @@ void DocumentViewerImpl::Notify(nsIImageGroup *aImageGroup,
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::SetEnableRendering(PRBool aOn)
|
DocumentViewerImpl::SetEnableRendering(PRBool aOn)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
mEnableRendering = aOn;
|
mEnableRendering = aOn;
|
||||||
if (mViewManager) {
|
if (mViewManager) {
|
||||||
if (aOn) {
|
if (aOn) {
|
||||||
|
@ -1832,6 +1801,7 @@ DocumentViewerImpl::SetEnableRendering(PRBool aOn)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::GetEnableRendering(PRBool* aResult)
|
DocumentViewerImpl::GetEnableRendering(PRBool* aResult)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(nsnull != aResult, "null OUT ptr");
|
NS_PRECONDITION(nsnull != aResult, "null OUT ptr");
|
||||||
if (aResult) {
|
if (aResult) {
|
||||||
*aResult = mEnableRendering;
|
*aResult = mEnableRendering;
|
||||||
|
@ -2606,6 +2576,7 @@ DocumentViewerImpl::GetPrintable(PRBool *aPrintable)
|
||||||
NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode)
|
NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(aNode);
|
NS_ENSURE_ARG(aNode);
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
nsCOMPtr<nsIPresShell> presShell;
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE);
|
NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
@ -2844,6 +2815,8 @@ NS_IMETHODIMP DocumentViewerImpl::SetHintCharacterSet(const PRUnichar* aHintChar
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::SizeToContent()
|
NS_IMETHODIMP DocumentViewerImpl::SizeToContent()
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mContainer));
|
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mContainer));
|
||||||
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
|
|
@ -1666,7 +1666,10 @@ NS_IMETHODIMP nsDocShell::Destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mContentViewer = nsnull;
|
if (mContentViewer) {
|
||||||
|
mContentViewer->Destroy();
|
||||||
|
mContentViewer = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
DestroyChildren();
|
DestroyChildren();
|
||||||
|
|
||||||
|
@ -2912,7 +2915,11 @@ NS_IMETHODIMP nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer)
|
||||||
mContentViewer->Stop();
|
mContentViewer->Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
mContentViewer = nsnull;
|
if (mContentViewer) {
|
||||||
|
mContentViewer->Destroy();
|
||||||
|
mContentViewer = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
// End copying block (Don't hold content/document viewer ref beyond here!!)
|
// End copying block (Don't hold content/document viewer ref beyond here!!)
|
||||||
|
|
||||||
// See the book I wrote above regarding why the focus controller is
|
// See the book I wrote above regarding why the focus controller is
|
||||||
|
@ -3368,8 +3375,8 @@ NS_IMETHODIMP nsDocShell::AddHeadersToChannel(nsIInputStream *aHeadersData,
|
||||||
nsCAutoString oneHeader;
|
nsCAutoString oneHeader;
|
||||||
nsCAutoString headerName;
|
nsCAutoString headerName;
|
||||||
nsCAutoString headerValue;
|
nsCAutoString headerValue;
|
||||||
PRUint32 crlf = 0;
|
PRInt32 crlf = 0;
|
||||||
PRUint32 colon = 0;
|
PRInt32 colon = 0;
|
||||||
nsIAtom *headerAtom;
|
nsIAtom *headerAtom;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -376,7 +376,7 @@ NS_NewDocumentViewer(nsIDocumentViewer** aResult)
|
||||||
// Note: operator new zeros our memory
|
// Note: operator new zeros our memory
|
||||||
DocumentViewerImpl::DocumentViewerImpl()
|
DocumentViewerImpl::DocumentViewerImpl()
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_ISUPPORTS();
|
||||||
mEnableRendering = PR_TRUE;
|
mEnableRendering = PR_TRUE;
|
||||||
mFilePointer = nsnull;
|
mFilePointer = nsnull;
|
||||||
mPrintListener = nsnull;
|
mPrintListener = nsnull;
|
||||||
|
@ -385,7 +385,7 @@ DocumentViewerImpl::DocumentViewerImpl()
|
||||||
DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext)
|
DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext)
|
||||||
: mPresContext(dont_QueryInterface(aPresContext))
|
: mPresContext(dont_QueryInterface(aPresContext))
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_ISUPPORTS();
|
||||||
mHintCharsetSource = kCharsetUninitialized;
|
mHintCharsetSource = kCharsetUninitialized;
|
||||||
mAllowPlugins = PR_TRUE;
|
mAllowPlugins = PR_TRUE;
|
||||||
mEnableRendering = PR_TRUE;
|
mEnableRendering = PR_TRUE;
|
||||||
|
@ -393,100 +393,24 @@ DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ISupports implementation...
|
NS_IMPL_ISUPPORTS5(DocumentViewerImpl,
|
||||||
NS_IMPL_ADDREF(DocumentViewerImpl)
|
nsIContentViewer,
|
||||||
NS_IMPL_RELEASE(DocumentViewerImpl)
|
nsIDocumentViewer,
|
||||||
|
nsIMarkupDocumentViewer,
|
||||||
nsresult
|
nsIContentViewerFile,
|
||||||
DocumentViewerImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
nsIContentViewerEdit)
|
||||||
{
|
|
||||||
if (NULL == aInstancePtr) {
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIContentViewer))) {
|
|
||||||
nsIContentViewer* tmp = this;
|
|
||||||
*aInstancePtr = (void*)tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIDocumentViewer))) {
|
|
||||||
nsIDocumentViewer* tmp = this;
|
|
||||||
*aInstancePtr = (void*) tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIMarkupDocumentViewer))) {
|
|
||||||
nsIMarkupDocumentViewer* tmp = this;
|
|
||||||
*aInstancePtr = (void*) tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIContentViewerFile))) {
|
|
||||||
nsIContentViewerFile* tmp = this;
|
|
||||||
*aInstancePtr = (void*) tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIContentViewerEdit))) {
|
|
||||||
nsIContentViewerEdit* tmp = this;
|
|
||||||
*aInstancePtr = (void*) tmp;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
|
||||||
nsIContentViewer* tmp1 = this;
|
|
||||||
nsISupports* tmp2 = tmp1;
|
|
||||||
*aInstancePtr = (void*) tmp2;
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
return NS_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DocumentViewerImpl::~DocumentViewerImpl()
|
DocumentViewerImpl::~DocumentViewerImpl()
|
||||||
{
|
{
|
||||||
nsresult rv;
|
NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Destroy");
|
||||||
|
if (mDocument)
|
||||||
if (mDocument) {
|
Destroy();
|
||||||
// Break global object circular reference on the document created
|
|
||||||
// in the DocViewer Init
|
|
||||||
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
||||||
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
||||||
if (globalObject) {
|
|
||||||
globalObject->SetNewDocument(nsnull);
|
|
||||||
}
|
|
||||||
// out of band cleanup of webshell
|
|
||||||
mDocument->SetScriptGlobalObject(nsnull);
|
|
||||||
if (mFocusListener) {
|
|
||||||
// get the DOM event receiver
|
|
||||||
nsCOMPtr<nsIDOMEventReceiver> erP;
|
|
||||||
rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP));
|
|
||||||
if(NS_SUCCEEDED(rv) && erP)
|
|
||||||
erP->RemoveEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// clear weak references before we go away
|
||||||
if (mPresContext) {
|
if (mPresContext) {
|
||||||
mPresContext->SetContainer(nsnull);
|
mPresContext->SetContainer(nsnull);
|
||||||
mPresContext->SetLinkHandler(nsnull);
|
mPresContext->SetLinkHandler(nsnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDeviceContext)
|
|
||||||
mDeviceContext->FlushFontCache();
|
|
||||||
|
|
||||||
if (mPresShell) {
|
|
||||||
// Break circular reference (or something)
|
|
||||||
mPresShell->EndObservingDocument();
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
rv = GetDocumentSelection(getter_AddRefs(selection));
|
|
||||||
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(selection));
|
|
||||||
if (NS_FAILED(rv) || !selPrivate)
|
|
||||||
return;
|
|
||||||
if (mSelectionListener)
|
|
||||||
selPrivate->RemoveSelectionListener(mSelectionListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -535,10 +459,7 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget,
|
||||||
const nsRect& aBounds)
|
const nsRect& aBounds)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER);
|
||||||
if (!mDocument) {
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDeviceContext = dont_QueryInterface(aDeviceContext);
|
mDeviceContext = dont_QueryInterface(aDeviceContext);
|
||||||
|
|
||||||
|
@ -689,13 +610,12 @@ NS_IMETHODIMP
|
||||||
DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||||
|
|
||||||
// First, get the script global object from the document...
|
// First, get the script global object from the document...
|
||||||
if (mDocument) {
|
rv = mDocument->GetScriptGlobalObject(getter_AddRefs(global));
|
||||||
rv = mDocument->GetScriptGlobalObject(getter_AddRefs(global));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fail if no ScriptGlobalObject is available...
|
// Fail if no ScriptGlobalObject is available...
|
||||||
NS_ASSERTION(global, "nsIScriptGlobalObject not set for document!");
|
NS_ASSERTION(global, "nsIScriptGlobalObject not set for document!");
|
||||||
|
@ -718,14 +638,56 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Destroy(void)
|
DocumentViewerImpl::Destroy()
|
||||||
{
|
{
|
||||||
return NS_ERROR_FAILURE;
|
// All callers are supposed to call destroy to break circular
|
||||||
|
// references. If we do this stuff in the destructor, the
|
||||||
|
// destructor might never be called (especially if we're being
|
||||||
|
// used from JS.
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
if (mDocument) {
|
||||||
|
// Break global object circular reference on the document created
|
||||||
|
// in the DocViewer Init
|
||||||
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
||||||
|
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
||||||
|
if (globalObject) {
|
||||||
|
globalObject->SetNewDocument(nsnull);
|
||||||
|
}
|
||||||
|
// out of band cleanup of webshell
|
||||||
|
mDocument->SetScriptGlobalObject(nsnull);
|
||||||
|
if (mFocusListener) {
|
||||||
|
// get the DOM event receiver
|
||||||
|
nsCOMPtr<nsIDOMEventReceiver> erP;
|
||||||
|
rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP));
|
||||||
|
if(NS_SUCCEEDED(rv) && erP)
|
||||||
|
erP->RemoveEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDeviceContext)
|
||||||
|
mDeviceContext->FlushFontCache();
|
||||||
|
|
||||||
|
if (mPresShell) {
|
||||||
|
// Break circular reference (or something)
|
||||||
|
mPresShell->EndObservingDocument();
|
||||||
|
nsCOMPtr<nsISelection> selection;
|
||||||
|
rv = GetDocumentSelection(getter_AddRefs(selection));
|
||||||
|
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(selection));
|
||||||
|
if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener)
|
||||||
|
selPrivate->RemoveSelectionListener(mSelectionListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
mDocument = nsnull;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Stop(void)
|
DocumentViewerImpl::Stop(void)
|
||||||
{
|
{
|
||||||
|
NS_ASSERTION(mDocument, "Stop called too early or too late");
|
||||||
if (mDocument) {
|
if (mDocument) {
|
||||||
mDocument->StopDocumentLoad();
|
mDocument->StopDocumentLoad();
|
||||||
}
|
}
|
||||||
|
@ -740,6 +702,7 @@ DocumentViewerImpl::Stop(void)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::GetDOMDocument(nsIDOMDocument **aResult)
|
DocumentViewerImpl::GetDOMDocument(nsIDOMDocument **aResult)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
return CallQueryInterface(mDocument.get(), aResult);
|
return CallQueryInterface(mDocument.get(), aResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,6 +809,7 @@ DocumentViewerImpl::GetPresContext(nsIPresContext*& aResult)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::GetBounds(nsRect& aResult)
|
DocumentViewerImpl::GetBounds(nsRect& aResult)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
mWindow->GetBounds(aResult);
|
mWindow->GetBounds(aResult);
|
||||||
|
@ -859,6 +823,7 @@ DocumentViewerImpl::GetBounds(nsRect& aResult)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::SetBounds(const nsRect& aBounds)
|
DocumentViewerImpl::SetBounds(const nsRect& aBounds)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
// Don't have the widget repaint. Layout will generate repaint requests
|
// Don't have the widget repaint. Layout will generate repaint requests
|
||||||
|
@ -872,6 +837,7 @@ DocumentViewerImpl::SetBounds(const nsRect& aBounds)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Move(PRInt32 aX, PRInt32 aY)
|
DocumentViewerImpl::Move(PRInt32 aX, PRInt32 aY)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
mWindow->Move(aX, aY);
|
mWindow->Move(aX, aY);
|
||||||
|
@ -882,6 +848,7 @@ DocumentViewerImpl::Move(PRInt32 aX, PRInt32 aY)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Show(void)
|
DocumentViewerImpl::Show(void)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
mWindow->Show(PR_TRUE);
|
mWindow->Show(PR_TRUE);
|
||||||
|
@ -892,6 +859,7 @@ DocumentViewerImpl::Show(void)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::Hide(void)
|
DocumentViewerImpl::Hide(void)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(mWindow, "null window");
|
NS_PRECONDITION(mWindow, "null window");
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
mWindow->Show(PR_FALSE);
|
mWindow->Show(PR_FALSE);
|
||||||
|
@ -1812,6 +1780,7 @@ void DocumentViewerImpl::Notify(nsIImageGroup *aImageGroup,
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::SetEnableRendering(PRBool aOn)
|
DocumentViewerImpl::SetEnableRendering(PRBool aOn)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
mEnableRendering = aOn;
|
mEnableRendering = aOn;
|
||||||
if (mViewManager) {
|
if (mViewManager) {
|
||||||
if (aOn) {
|
if (aOn) {
|
||||||
|
@ -1832,6 +1801,7 @@ DocumentViewerImpl::SetEnableRendering(PRBool aOn)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DocumentViewerImpl::GetEnableRendering(PRBool* aResult)
|
DocumentViewerImpl::GetEnableRendering(PRBool* aResult)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
NS_PRECONDITION(nsnull != aResult, "null OUT ptr");
|
NS_PRECONDITION(nsnull != aResult, "null OUT ptr");
|
||||||
if (aResult) {
|
if (aResult) {
|
||||||
*aResult = mEnableRendering;
|
*aResult = mEnableRendering;
|
||||||
|
@ -2606,6 +2576,7 @@ DocumentViewerImpl::GetPrintable(PRBool *aPrintable)
|
||||||
NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode)
|
NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(aNode);
|
NS_ENSURE_ARG(aNode);
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
nsCOMPtr<nsIPresShell> presShell;
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE);
|
NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
@ -2844,6 +2815,8 @@ NS_IMETHODIMP DocumentViewerImpl::SetHintCharacterSet(const PRUnichar* aHintChar
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::SizeToContent()
|
NS_IMETHODIMP DocumentViewerImpl::SizeToContent()
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mContainer));
|
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mContainer));
|
||||||
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче