diff --git a/mozilla/editor/libeditor/base/nsEditor.cpp b/mozilla/editor/libeditor/base/nsEditor.cpp index 45cf4bc97de..eaa883f7d7d 100644 --- a/mozilla/editor/libeditor/base/nsEditor.cpp +++ b/mozilla/editor/libeditor/base/nsEditor.cpp @@ -41,6 +41,7 @@ #include "nsIDOMDocument.h" #include "nsIDOMHTMLDocument.h" #include "nsIDOMHTMLElement.h" +#include "nsIDOMEventReceiver.h" #include "nsIPrefBranch.h" #include "nsIPrefService.h" #include "nsUnicharUtils.h" @@ -54,6 +55,14 @@ #include "nsIDOMNamedNodeMap.h" #include "nsIDOMNodeList.h" #include "nsIDOMRange.h" +#include "nsIDOM3EventTarget.h" +#include "nsIDOMEventListener.h" +#include "nsIDOMEventGroup.h" +#include "nsIDOMMouseListener.h" +#include "nsIDOMFocusListener.h" +#include "nsIDOMTextListener.h" +#include "nsIDOMCompositionListener.h" +#include "nsIDOMDragListener.h" #include "nsIDocument.h" #include "nsITransactionManager.h" #include "nsIAbsorbingTransaction.h" @@ -142,7 +151,6 @@ nsEditor::nsEditor() , mSavedSel() , mRangeUpdater() , mShouldTxnSetSelection(PR_TRUE) -, mBodyElement(nsnull) , mAction(nsnull) , mDirection(eNone) , mInIMEMode(PR_FALSE) @@ -269,11 +277,9 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot nsCOMPtr ps = do_QueryReferent(mPresShellWeak); if (!ps) return NS_ERROR_NOT_INITIALIZED; - //set up body element if we are passed one. + //set up root element if we are passed one. if (aRoot) - mBodyElement = do_QueryInterface(aRoot); - - + mRootElement = do_QueryInterface(aRoot); // Set up the DTD // XXX - in the long run we want to get this from the document, but there @@ -331,6 +337,17 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot NS_IMETHODIMP nsEditor::PostCreate() { + nsresult rv = CreateEventListeners(); + if (NS_FAILED(rv)) + { + RemoveEventListeners(); + + return rv; + } + + rv = InstallEventListeners(); + NS_ENSURE_SUCCESS(rv, rv); + // nuke the modification count, so the doc appears unmodified // do this before we notify listeners ResetModificationCount(); @@ -345,12 +362,132 @@ nsEditor::PostCreate() return NS_OK; } +nsresult +nsEditor::InstallEventListeners() +{ + NS_ENSURE_TRUE(mDocWeak && mPresShellWeak && mKeyListenerP && + mMouseListenerP && mFocusListenerP && mTextListenerP && + mCompositionListenerP && mDragListenerP, + NS_ERROR_NOT_INITIALIZED); + + nsCOMPtr erP = GetDOMEventReceiver(); + + if (!erP) { + RemoveEventListeners(); + return NS_ERROR_FAILURE; + } + + nsresult rv = NS_OK; + + // register the event listeners with the DOM event reveiver + nsCOMPtr dom3Targ(do_QueryInterface(erP)); + nsCOMPtr sysGroup; + erP->GetSystemEventGroup(getter_AddRefs(sysGroup)); + + if (sysGroup) + { + rv = dom3Targ->AddGroupedEventListener(NS_LITERAL_STRING("keypress"), + mKeyListenerP, PR_FALSE, sysGroup); + NS_ASSERTION(NS_SUCCEEDED(rv), + "failed to register key listener in system group"); + } + + rv |= erP->AddEventListenerByIID(mMouseListenerP, + NS_GET_IID(nsIDOMMouseListener)); + + rv |= erP->AddEventListenerByIID(mFocusListenerP, + NS_GET_IID(nsIDOMFocusListener)); + + rv |= erP->AddEventListenerByIID(mTextListenerP, + NS_GET_IID(nsIDOMTextListener)); + + rv |= erP->AddEventListenerByIID(mCompositionListenerP, + NS_GET_IID(nsIDOMCompositionListener)); + + rv |= erP->AddEventListenerByIID(mDragListenerP, + NS_GET_IID(nsIDOMDragListener)); + + if (NS_FAILED(rv)) + { + NS_ERROR("failed to register some event listeners"); + + RemoveEventListeners(); + } + + return rv; +} + +void +nsEditor::RemoveEventListeners() +{ + nsCOMPtr erP = GetDOMEventReceiver(); + + if (erP) + { + // unregister the event listeners with the DOM event reveiver + + if (mKeyListenerP) + { + nsCOMPtr sysGroup; + erP->GetSystemEventGroup(getter_AddRefs(sysGroup)); + if (sysGroup) + { + nsCOMPtr dom3Targ(do_QueryInterface(erP)); + + dom3Targ->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"), + mKeyListenerP, PR_FALSE, + sysGroup); + } + } + + if (mMouseListenerP) + { + erP->RemoveEventListenerByIID(mMouseListenerP, + NS_GET_IID(nsIDOMMouseListener)); + } + + if (mFocusListenerP) + { + erP->RemoveEventListenerByIID(mFocusListenerP, + NS_GET_IID(nsIDOMFocusListener)); + } + + if (mTextListenerP) + { + erP->RemoveEventListenerByIID(mTextListenerP, + NS_GET_IID(nsIDOMTextListener)); + } + + if (mCompositionListenerP) + { + erP->RemoveEventListenerByIID(mCompositionListenerP, + NS_GET_IID(nsIDOMCompositionListener)); + } + + if (mDragListenerP) + { + erP->RemoveEventListenerByIID(mDragListenerP, + NS_GET_IID(nsIDOMDragListener)); + } + } + + mKeyListenerP = nsnull; + mMouseListenerP = nsnull; + mFocusListenerP = nsnull; + mTextListenerP = nsnull; + mCompositionListenerP = nsnull; + mDragListenerP = nsnull; +} NS_IMETHODIMP nsEditor::PreDestroy() { // tell our listeners that the doc is going away NotifyDocumentListeners(eDocumentToBeDestroyed); + + // Unregister event listeners + RemoveEventListeners(); + return NS_OK; } @@ -854,15 +991,17 @@ nsEditor::SetShouldTxnSetSelection(PRBool aShould) NS_IMETHODIMP nsEditor::GetDocumentIsEmpty(PRBool *aDocumentIsEmpty) { - nsCOMPtr rootElement; - nsresult res = GetRootElement(getter_AddRefs(rootElement)); - if (NS_FAILED(res)) return res; - if (!rootElement) return NS_ERROR_NULL_POINTER; - nsCOMPtr rootNode = do_QueryInterface(rootElement); - nsCOMPtr firstChild; - res = rootNode->GetFirstChild(getter_AddRefs(firstChild)); + *aDocumentIsEmpty = PR_TRUE; + + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) + return NS_ERROR_NULL_POINTER; + + PRBool hasChildNodes; + nsresult res = rootElement->HasChildNodes(&hasChildNodes); + + *aDocumentIsEmpty = !hasChildNodes; - *aDocumentIsEmpty = NS_SUCCEEDED(res) && firstChild; return res; } @@ -897,10 +1036,9 @@ NS_IMETHODIMP nsEditor::BeginningOfDocument() return NS_ERROR_NOT_INITIALIZED; // get the root element - nsCOMPtr rootElement; - result = GetRootElement(getter_AddRefs(rootElement)); - if (NS_FAILED(result)) return result; - if (!rootElement) return NS_ERROR_NULL_POINTER; + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) + return NS_ERROR_NULL_POINTER; // find first editable thingy nsCOMPtr firstNode; @@ -926,7 +1064,7 @@ NS_IMETHODIMP nsEditor::BeginningOfDocument() } else { - // just the body node, set selection to inside the body + // just the root node, set selection to inside the root result = selection->Collapse(rootElement, 0); } return result; @@ -937,7 +1075,7 @@ nsEditor::EndOfDocument() { if (!mDocWeak || !mPresShellWeak) { return NS_ERROR_NOT_INITIALIZED; } nsresult res; - + // get selection nsCOMPtr selection; res = GetSelection(getter_AddRefs(selection)); @@ -945,19 +1083,17 @@ nsEditor::EndOfDocument() if (!selection) return NS_ERROR_NULL_POINTER; // get the root element - nsCOMPtr rootElement; - res = GetRootElement(getter_AddRefs(rootElement)); - if (NS_FAILED(res)) return res; - if (!rootElement) return NS_ERROR_NULL_POINTER; - nsCOMPtr rootNode = do_QueryInterface(rootElement); - + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) + return NS_ERROR_NULL_POINTER; + // get the length of the rot element PRUint32 len; - res = GetLengthOfDOMNode(rootNode, len); - if (NS_FAILED(res)) return res; - + res = GetLengthOfDOMNode(rootElement, len); + if (NS_FAILED(res)) return res; + // set the selection to after the last child of the root element - return selection->Collapse(rootNode, (PRInt32)len); + return selection->Collapse(rootElement, (PRInt32)len); } NS_IMETHODIMP @@ -1798,7 +1934,7 @@ NS_IMETHODIMP nsEditor::DumpContentTree() { #ifdef DEBUG - nsCOMPtr root = do_QueryInterface(mBodyElement); + nsCOMPtr root = do_QueryInterface(mRootElement); if (root) root->List(stdout); #endif return NS_OK; @@ -2073,7 +2209,7 @@ nsEditor::GetKBStateControl(nsIKBStateControl **aKBSC) return NS_ERROR_FAILURE; nsCOMPtr widget; - res = GetEditorContentWindow(shell, mBodyElement, getter_AddRefs(widget)); + res = GetEditorContentWindow(shell, GetRoot(), getter_AddRefs(widget)); if (NS_FAILED(res)) return res; @@ -2224,40 +2360,40 @@ nsEditor::GetQueryCaretRect(nsQueryCaretRectEventReply* aReply) /* Non-interface, public methods */ -// This seems like too much work! There should be a "nsDOMDocument::GetBody()" -// Have a look in nsHTMLDocument. Maybe add it to nsIHTMLDocument. NS_IMETHODIMP -nsEditor::GetRootElement(nsIDOMElement **aBodyElement) +nsEditor::GetRootElement(nsIDOMElement **aRootElement) { - if (!aBodyElement) + if (!aRootElement) return NS_ERROR_NULL_POINTER; - *aBodyElement = 0; - - if (mBodyElement) + if (mRootElement) { // if we have cached the body element, use that - *aBodyElement = mBodyElement; - NS_ADDREF(*aBodyElement); + *aRootElement = mRootElement; + NS_ADDREF(*aRootElement); return NS_OK; } - + + *aRootElement = 0; + NS_PRECONDITION(mDocWeak, "bad state, null mDocWeak"); nsCOMPtr doc = do_QueryReferent(mDocWeak); if (!doc) return NS_ERROR_NOT_INITIALIZED; - nsCOMPtrbodyElement; + // Use the documents body element as the editor root if we didn't + // get a root element during initialization. + + nsCOMPtr bodyElement; nsresult result = doc->GetBody(getter_AddRefs(bodyElement)); if (NS_FAILED(result)) return result; - + if (!bodyElement) return NS_ERROR_NULL_POINTER; - // Use the first body node in the list: - mBodyElement = do_QueryInterface(bodyElement); - *aBodyElement = bodyElement; - NS_ADDREF(*aBodyElement); + mRootElement = bodyElement; + *aRootElement = bodyElement; + NS_ADDREF(*aRootElement); return NS_OK; } @@ -2335,15 +2471,14 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode) // Use transaction system for undo only if destination // is already in the document - nsCOMPtr bodyElement; - nsresult result = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(result)) return result; - if (!bodyElement) return NS_ERROR_NULL_POINTER; + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) + return NS_ERROR_NULL_POINTER; PRBool destInBody = PR_TRUE; - nsCOMPtr bodyNode = do_QueryInterface(bodyElement); + nsCOMPtr rootNode = do_QueryInterface(rootElement); nsCOMPtr p = aDestNode; - while (p && p!= bodyNode) + while (p && p != rootNode) { nsCOMPtr tmp; if (NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp) @@ -2380,6 +2515,9 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode) } } } + + nsresult result = NS_OK; + // Set just the attributes that the source element has for (i = 0; i < sourceCount; i++) { @@ -2653,20 +2791,11 @@ NS_IMETHODIMP nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToIns NS_IMETHODIMP nsEditor::SelectEntireDocument(nsISelection *aSelection) { if (!aSelection) { return NS_ERROR_NULL_POINTER; } - nsCOMPtrbodyElement; - nsresult result = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_SUCCEEDED(result)) - { - nsCOMPtrbodyNode = do_QueryInterface(bodyElement); - if (bodyNode) - { - result = aSelection->SelectAllChildren(bodyNode); - } - else { - return NS_ERROR_NO_INTERFACE; - } - } - return result; + + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) { return NS_ERROR_NOT_INITIALIZED; } + + return aSelection->SelectAllChildren(rootElement); } @@ -3737,27 +3866,21 @@ nsEditor::IsRootNode(nsIDOMNode *inNode) if (!inNode) return PR_FALSE; - nsCOMPtr rootElement; - - nsresult result = GetRootElement(getter_AddRefs(rootElement)); - - if (NS_FAILED(result) || !rootElement) - return PR_FALSE; + nsIDOMElement *rootElement = GetRoot(); nsCOMPtr rootNode = do_QueryInterface(rootElement); - - return inNode == rootNode.get(); + + return inNode == rootNode; } PRBool nsEditor::IsDescendantOfBody(nsIDOMNode *inNode) { if (!inNode) return PR_FALSE; - nsCOMPtr junk; - if (!mBodyElement) GetRootElement(getter_AddRefs(junk)); - if (!mBodyElement) return PR_FALSE; - nsCOMPtr root = do_QueryInterface(mBodyElement); - + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) return PR_FALSE; + nsCOMPtr root = do_QueryInterface(rootElement); + if (inNode == root.get()) return PR_TRUE; nsCOMPtr parent, node = do_QueryInterface(inNode); @@ -5275,15 +5398,68 @@ nsEditor::HandleInlineSpellCheck(PRInt32 action, aEndOffset) : NS_OK; } +already_AddRefed +nsEditor::GetDOMEventReceiver() +{ + nsIDOMEventReceiver *erp = nsnull; + + nsIDOMElement *rootElement = GetRoot(); + + // Now hack to make sure we are not anonymous content. + // If we are grab the parent of root element for our observer. + + nsCOMPtr content = do_QueryInterface(rootElement); + + if (content) + { + nsIContent* parent = content->GetParent(); + if (parent) + { + if (parent->IndexOf(content) < 0) + { + // this will put listener on the form element basically + CallQueryInterface(parent, &erp); + } + } + } + + if (!erp) + { + // Don't use getDocument here, because we have no way of knowing + // if Init() was ever called. So we need to get the document + // ourselves, if it exists. + + nsCOMPtr domdoc = do_QueryReferent(mDocWeak); + if (domdoc) + { + CallQueryInterface(domdoc, &erp); + } + } + + return erp; +} + +nsIDOMElement * +nsEditor::GetRoot() +{ + if (!mRootElement) + { + nsCOMPtr root; + + // Let GetRootElement() do the work + GetRootElement(getter_AddRefs(root)); + } + + return mRootElement; +} + NS_IMETHODIMP nsEditor::SwitchTextDirection() { - // Get the current body direction from its frame - nsCOMPtr rootElement; - nsresult rv = GetRootElement(getter_AddRefs(rootElement)); - if (NS_FAILED(rv)) - return rv; + // Get the current root direction from its frame + nsIDOMElement *rootElement = GetRoot(); + nsresult rv; nsCOMPtr content = do_QueryInterface(rootElement, &rv); if (NS_FAILED(rv)) return rv; diff --git a/mozilla/editor/libeditor/base/nsEditor.h b/mozilla/editor/libeditor/base/nsEditor.h index 90ac39610d6..88eac18e54c 100644 --- a/mozilla/editor/libeditor/base/nsEditor.h +++ b/mozilla/editor/libeditor/base/nsEditor.h @@ -85,6 +85,7 @@ class AddStyleSheetTxn; class RemoveStyleSheetTxn; class nsIFile; class nsISelectionController; +class nsIDOMEventReceiver; #define kMOZEditorBogusNodeAttr NS_LITERAL_STRING("_moz_editor_bogus_node") #define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE") @@ -331,6 +332,16 @@ protected: // Get nsIKBStateControl interface nsresult GetKBStateControl(nsIKBStateControl **aKBSC); + + + // install the event listeners for the editor + nsresult InstallEventListeners(); + + virtual nsresult CreateEventListeners() = 0; + + // unregister and release our event listeners + virtual void RemoveEventListeners(); + public: /** All editor operations which alter the doc should be prefaced @@ -558,6 +569,11 @@ public: nsIDOMNode *aEndNode, PRInt32 aEndOffset); + already_AddRefed GetDOMEventReceiver(); + + // Fast non-refcounting editor root element accessor + nsIDOMElement *GetRoot(); + public: // Argh! These transaction names are used by PlaceholderTxn and // nsPlaintextEditor. They should be localized to those classes. @@ -583,7 +599,7 @@ protected: nsSelectionState mSavedSel; // cached selection for nsAutoSelectionReset nsRangeUpdater mRangeUpdater; // utility class object for maintaining preserved ranges PRBool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns - nsCOMPtr mBodyElement; // cached body node + nsCOMPtr mRootElement; // cached root node PRInt32 mAction; // the current editor action EDirection mDirection; // the current direction of editor action @@ -608,6 +624,13 @@ protected: nsString* mPhonetic; + nsCOMPtr mKeyListenerP; + nsCOMPtr mMouseListenerP; + nsCOMPtr mTextListenerP; + nsCOMPtr mCompositionListenerP; + nsCOMPtr mDragListenerP; + nsCOMPtr mFocusListenerP; + static PRInt32 gInstanceCount; friend PRBool NSCanUnload(nsISupports* serviceMgr); diff --git a/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp b/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp index 10a6ea20716..0f6ec4020ae 100644 --- a/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp @@ -321,16 +321,14 @@ nsHTMLEditor::HideGrabber() // get the root content node. - nsCOMPtr bodyElement; - res = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; + nsIDOMElement *rootElement = GetRoot(); - nsCOMPtr bodyContent = do_QueryInterface(bodyElement); - if (!bodyContent) return NS_ERROR_NULL_POINTER; + nsCOMPtr rootContent = do_QueryInterface(rootElement); + if (!rootContent) return NS_ERROR_NULL_POINTER; - DeleteRefToAnonymousNode(mGrabber, bodyContent, docObserver); + DeleteRefToAnonymousNode(mGrabber, rootContent, docObserver); mGrabber = nsnull; - DeleteRefToAnonymousNode(mPositioningShadow, bodyContent, docObserver); + DeleteRefToAnonymousNode(mPositioningShadow, rootContent, docObserver); mPositioningShadow = nsnull; return NS_OK; @@ -352,12 +350,10 @@ nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement) // first, let's keep track of that element... mAbsolutelyPositionedObject = aElement; - nsCOMPtr bodyElement; - res = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; - if (!bodyElement) return NS_ERROR_NULL_POINTER; + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) return NS_ERROR_NULL_POINTER; - res = CreateGrabber(bodyElement, getter_AddRefs(mGrabber)); + res = CreateGrabber(rootElement, getter_AddRefs(mGrabber)); if (NS_FAILED(res)) return res; // and set its position return RefreshGrabber(); @@ -366,14 +362,12 @@ nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement) nsresult nsHTMLEditor::StartMoving(nsIDOMElement *aHandle) { - nsCOMPtr bodyElement; - nsresult result = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(result)) return result; - if (!bodyElement) return NS_ERROR_NULL_POINTER; + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) return NS_ERROR_NULL_POINTER; // now, let's create the resizing shadow - result = CreateShadow(getter_AddRefs(mPositioningShadow), bodyElement, - mAbsolutelyPositionedObject); + nsresult result = CreateShadow(getter_AddRefs(mPositioningShadow), + rootElement, mAbsolutelyPositionedObject); if (NS_FAILED(result)) return result; result = SetShadowPosition(mPositioningShadow, mAbsolutelyPositionedObject, mPositionedObjectX, mPositionedObjectY); @@ -412,15 +406,13 @@ nsHTMLEditor::GrabberClicked() mMouseMotionListenerP = new ResizerMouseMotionListener(this); if (!mMouseMotionListenerP) {return NS_ERROR_NULL_POINTER;} - nsCOMPtr erP; - res = GetDOMEventReceiver(getter_AddRefs(erP)); - if (NS_SUCCEEDED(res )) - { - res = erP->AddEventListenerByIID(mMouseMotionListenerP, NS_GET_IID(nsIDOMMouseMotionListener)); - NS_ASSERTION(NS_SUCCEEDED(res), "failed to register mouse motion listener"); - } - else - HandleEventListenerError(); + nsCOMPtr erP = GetDOMEventReceiver(); + NS_ENSURE_TRUE(erP, NS_ERROR_FAILURE); + + res = erP->AddEventListenerByIID(mMouseMotionListenerP, + NS_GET_IID(nsIDOMMouseMotionListener)); + NS_ASSERTION(NS_SUCCEEDED(res), + "failed to register mouse motion listener"); } mGrabberClicked = PR_TRUE; return res; @@ -438,21 +430,21 @@ nsHTMLEditor::EndMoving() // get the root content node. - nsCOMPtr bodyElement; - nsresult res = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; + nsIDOMElement *rootElement = GetRoot(); - nsCOMPtr bodyContent( do_QueryInterface(bodyElement) ); - if (!bodyContent) return NS_ERROR_FAILURE; + nsCOMPtr rootContent( do_QueryInterface(rootElement) ); + if (!rootContent) return NS_ERROR_FAILURE; - DeleteRefToAnonymousNode(mPositioningShadow, bodyContent, docObserver); + DeleteRefToAnonymousNode(mPositioningShadow, rootContent, docObserver); mPositioningShadow = nsnull; } - nsCOMPtr erP; - nsresult res = GetDOMEventReceiver(getter_AddRefs(erP)); + nsCOMPtr erP = GetDOMEventReceiver(); - if (NS_SUCCEEDED(res) && erP && mMouseMotionListenerP) { - res = erP->RemoveEventListenerByIID(mMouseMotionListenerP, NS_GET_IID(nsIDOMMouseMotionListener)); + if (erP && mMouseMotionListenerP) { +#ifdef DEBUG + nsresult res = +#endif + erP->RemoveEventListenerByIID(mMouseMotionListenerP, NS_GET_IID(nsIDOMMouseMotionListener)); NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove mouse motion listener"); } mMouseMotionListenerP = nsnull; diff --git a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp index 3ec9aeaf1d7..2ca217ce20b 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp @@ -274,11 +274,8 @@ nsHTMLEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags) if (!mUtilRange) return NS_ERROR_NULL_POINTER; // set up mDocChangeRange to be whole doc - nsCOMPtr bodyElem; - nsCOMPtr bodyNode; - mHTMLEditor->GetRootElement(getter_AddRefs(bodyElem)); - bodyNode = do_QueryInterface(bodyElem); - if (bodyNode) + nsIDOMElement *rootElem = mHTMLEditor->GetRoot(); + if (rootElem) { // temporarily turn off rules sniffing nsAutoLockRulesSniffing lockIt((nsTextEditRules*)this); @@ -287,7 +284,7 @@ nsHTMLEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags) mDocChangeRange = do_CreateInstance("@mozilla.org/content/range;1"); if (!mDocChangeRange) return NS_ERROR_NULL_POINTER; } - mDocChangeRange->SelectNode(bodyNode); + mDocChangeRange->SelectNode(rootElem); res = AdjustSpecialBreaks(); if (NS_FAILED(res)) return res; } @@ -792,10 +789,11 @@ nsHTMLEditRules::GetAlignment(PRBool *aMixed, nsIHTMLEditor::EAlignment *aAlign) // get selection location nsCOMPtr parent; - nsCOMPtr rootElem; + nsIDOMElement *rootElem = mHTMLEditor->GetRoot(); + if (!rootElem) + return NS_ERROR_FAILURE; + PRInt32 offset, rootOffset; - res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElem)); - if (NS_FAILED(res)) return res; res = nsEditor::GetNodeLocation(rootElem, address_of(parent), &rootOffset); if (NS_FAILED(res)) return res; res = mHTMLEditor->GetStartNodeAndOffset(selection, address_of(parent), &offset); @@ -994,12 +992,10 @@ nsHTMLEditRules::GetIndentState(PRBool *aCanIndent, PRBool *aCanOutdent) // gather up info we need for test nsCOMPtr parent, tmp, root; - nsCOMPtr rootElem; + nsIDOMElement *rootElem = mHTMLEditor->GetRoot(); + if (!rootElem) return NS_ERROR_NULL_POINTER; nsCOMPtr selection; PRInt32 selOffset; - res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElem)); - if (NS_FAILED(res)) return res; - if (!rootElem) return NS_ERROR_NULL_POINTER; root = do_QueryInterface(rootElem); if (!root) return NS_ERROR_NO_INTERFACE; res = mHTMLEditor->GetSelection(getter_AddRefs(selection)); @@ -1092,9 +1088,7 @@ nsHTMLEditRules::GetParagraphState(PRBool *aMixed, nsAString &outFormat) } // remember root node - nsCOMPtr rootElem; - res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElem)); - if (NS_FAILED(res)) return res; + nsIDOMElement *rootElem = mHTMLEditor->GetRoot(); if (!rootElem) return NS_ERROR_NULL_POINTER; // loop through the nodes in selection and examine their paragraph format @@ -1869,17 +1863,13 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection, if (!startNode) return NS_ERROR_FAILURE; // get the root element - nsCOMPtr bodyNode; - { - res = mHTMLEditor->GetRootElement(getter_AddRefs(bodyNode)); - if (NS_FAILED(res)) return res; - if (!bodyNode) return NS_ERROR_UNEXPECTED; - } + nsIDOMElement *rootNode = mHTMLEditor->GetRoot(); + if (!rootNode) return NS_ERROR_UNEXPECTED; if (bCollapsed) { // if we are inside an empty block, delete it. - res = CheckForEmptyBlock(startNode, bodyNode, aSelection, aHandled); + res = CheckForEmptyBlock(startNode, rootNode, aSelection, aHandled); if (NS_FAILED(res)) return res; if (*aHandled) return NS_OK; @@ -3313,7 +3303,7 @@ nsHTMLEditRules::WillMakeBasicBlock(nsISelection *aSelection, res = mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(parent), &offset); if (NS_FAILED(res)) return res; if (tString.EqualsLiteral("normal") || - tString.IsEmpty() ) // we are removing blocks (going to "body text") + tString.IsEmpty() ) // we are removing blocks (going to "body text") { nsCOMPtr curBlock = parent; if (!IsBlockNode(curBlock)) @@ -3822,7 +3812,7 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool * // or whatever is appropriate. Wohoo! nsCOMPtr curBlockQuote, firstBQChild, lastBQChild; - PRBool curBlockQuoteIsIndentedWithCSS; + PRBool curBlockQuoteIsIndentedWithCSS = PR_FALSE; PRInt32 listCount = arrayOfNodes.Count(); PRInt32 i; nsCOMPtr curParent; @@ -4921,9 +4911,10 @@ nsHTMLEditRules::ExpandSelectionForDeletion(nsISelection *aSelection) nsCOMPtr visNode, firstBRParent; PRInt32 visOffset=0, firstBROffset=0; PRInt16 wsType; - nsCOMPtr rootElement; - res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElement)); - + nsIDOMElement *rootElement = mHTMLEditor->GetRoot(); + if (!rootElement) + return NS_ERROR_FAILURE; + // find previous visible thingy before start of selection if ((selStartNode!=selCommon) && (selStartNode!=rootElement)) { @@ -5507,13 +5498,10 @@ nsHTMLEditRules::PromoteRange(nsIDOMRange *inRange, { PRBool bIsEmptyNode = PR_FALSE; // check for body - nsCOMPtr bodyElement; - nsCOMPtr bodyNode; - res = mHTMLEditor->GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; - if (!bodyElement) return NS_ERROR_UNEXPECTED; - bodyNode = do_QueryInterface(bodyElement); - if (block != bodyNode) + nsIDOMElement *rootElement = mHTMLEditor->GetRoot(); + if (!rootElement) return NS_ERROR_UNEXPECTED; + nsCOMPtr rootNode = do_QueryInterface(rootElement); + if (block != rootNode) { // ok, not body, check if empty res = mHTMLEditor->IsEmptyNode(block, &bIsEmptyNode, PR_TRUE, PR_FALSE); @@ -7423,9 +7411,7 @@ nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection // check if br can go into the destination node if (bIsEmptyNode && mHTMLEditor->CanContainTag(selNode, NS_LITERAL_STRING("br"))) { - nsCOMPtr rootElement; - res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElement)); - if (NS_FAILED(res)) return res; + nsIDOMElement *rootElement = mHTMLEditor->GetRoot(); if (!rootElement) return NS_ERROR_FAILURE; nsCOMPtr rootNode(do_QueryInterface(rootElement)); if (selNode == rootNode) @@ -8003,14 +7989,10 @@ nsresult nsHTMLEditRules::ConfirmSelectionInBody() { nsresult res = NS_OK; - nsCOMPtr bodyElement; - nsCOMPtr bodyNode; - + // get the body - res = mHTMLEditor->GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; - if (!bodyElement) return NS_ERROR_UNEXPECTED; - bodyNode = do_QueryInterface(bodyElement); + nsIDOMElement *rootElement = mHTMLEditor->GetRoot(); + if (!rootElement) return NS_ERROR_UNEXPECTED; // get the selection nsCOMPtrselection; @@ -8036,7 +8018,7 @@ nsHTMLEditRules::ConfirmSelectionInBody() { // uncomment this to see when we get bad selections // NS_NOTREACHED("selection not in body"); - selection->Collapse(bodyNode,0); + selection->Collapse(rootElement, 0); } // get the selection end location @@ -8056,7 +8038,7 @@ nsHTMLEditRules::ConfirmSelectionInBody() { // uncomment this to see when we get bad selections // NS_NOTREACHED("selection not in body"); - selection->Collapse(bodyNode,0); + selection->Collapse(rootElement, 0); } return res; diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp index aa4e4134194..9f9edfb78d5 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp @@ -168,8 +168,9 @@ nsHTMLEditor::nsHTMLEditor() nsHTMLEditor::~nsHTMLEditor() { - // remove the rules as an action listener. Else we get a bad ownership loop later on. - // it's ok if the rules aren't a listener; we ignore the error. + // remove the rules as an action listener. Else we get a bad + // ownership loop later on. it's ok if the rules aren't a listener; + // we ignore the error. nsCOMPtr mListener = do_QueryInterface(mRules); RemoveEditActionListener(mListener); @@ -195,11 +196,12 @@ nsHTMLEditor::~nsHTMLEditor() NS_IF_RELEASE(mTypeInState); mSelectionListenerP = nsnull; - if (mHTMLCSSUtils) - delete mHTMLCSSUtils; - + delete mHTMLCSSUtils; + // free any default style propItems RemoveAllDefaultProperties(); + + RemoveEventListeners(); } /* static */ @@ -315,120 +317,61 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, return result; } -NS_IMETHODIMP -nsHTMLEditor::PostCreate() +nsresult +nsHTMLEditor::CreateEventListeners() { - nsresult result = InstallEventListeners(); - if (NS_FAILED(result)) return result; + nsresult rv = NS_OK; - result = nsEditor::PostCreate(); - return result; -} - -NS_IMETHODIMP -nsHTMLEditor::InstallEventListeners() -{ - NS_ASSERTION(mDocWeak, "no document set on this editor"); - if (!mDocWeak) return NS_ERROR_NOT_INITIALIZED; - - if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED; - - nsresult result; - // get a key listener - result = NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this); - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; - } - - // get a mouse listener - result = NS_NewHTMLEditorMouseListener(getter_AddRefs(mMouseListenerP), this); - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; - } - - // get a text listener - result = NS_NewEditorTextListener(getter_AddRefs(mTextListenerP),this); - if (NS_FAILED(result)) { -#ifdef DEBUG_TAGUE -printf("nsTextEditor.cpp: failed to get TextEvent Listener\n"); -#endif - HandleEventListenerError(); - return result; - } - - // get a composition listener - result = NS_NewEditorCompositionListener(getter_AddRefs(mCompositionListenerP),this); - if (NS_FAILED(result)) { -#ifdef DEBUG_TAGUE -printf("nsTextEditor.cpp: failed to get TextEvent Listener\n"); -#endif - HandleEventListenerError(); - return result; - } - - // get a drag listener - nsCOMPtr presShell = do_QueryReferent(mPresShellWeak); - result = NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), presShell, this); - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; - } - - // get a focus listener - result = NS_NewEditorFocusListener(getter_AddRefs(mFocusListenerP), this); - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; - } - - nsCOMPtr erP; - result = GetDOMEventReceiver(getter_AddRefs(erP)); - - //end hack - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; - } - - // register the event listeners with the DOM event reveiver - nsCOMPtr dom3Targ(do_QueryInterface(erP)); - nsCOMPtr sysGroup; - if (NS_SUCCEEDED(erP->GetSystemEventGroup(getter_AddRefs(sysGroup)))) { - result = dom3Targ->AddGroupedEventListener(NS_LITERAL_STRING("keypress"), mKeyListenerP, PR_FALSE, sysGroup); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register key listener in system group"); - } - - if (NS_SUCCEEDED(result)) + if (!mMouseListenerP) { - result = erP->AddEventListenerByIID(mMouseListenerP, NS_GET_IID(nsIDOMMouseListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register mouse listener"); - if (NS_SUCCEEDED(result)) + // get a mouse listener + rv = NS_NewHTMLEditorMouseListener(getter_AddRefs(mMouseListenerP), this); + + if (NS_FAILED(rv)) { - result = erP->AddEventListenerByIID(mFocusListenerP, NS_GET_IID(nsIDOMFocusListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register focus listener"); - if (NS_SUCCEEDED(result)) - { - result = erP->AddEventListenerByIID(mTextListenerP, NS_GET_IID(nsIDOMTextListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register text listener"); - if (NS_SUCCEEDED(result)) - { - result = erP->AddEventListenerByIID(mCompositionListenerP, NS_GET_IID(nsIDOMCompositionListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register composition listener"); - if (NS_SUCCEEDED(result)) - { - result = erP->AddEventListenerByIID(mDragListenerP, NS_GET_IID(nsIDOMDragListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register drag listener"); - } - } - } + return rv; } } - if (NS_FAILED(result)) { - HandleEventListenerError(); + + return nsPlaintextEditor::CreateEventListeners(); +} + +void +nsHTMLEditor::RemoveEventListeners() +{ + nsCOMPtr erP = GetDOMEventReceiver(); + + if (erP) + { + // Both mMouseMotionListenerP and mResizeEventListenerP can be + // registerd with other targets than the DOM event receiver that + // we can reach from here. But nonetheless, unregister the event + // listeners with the DOM event reveiver (if it's registerd with + // other targets, it'll get unregisterd once the target goes + // away). + + if (mMouseMotionListenerP) + { + // mMouseMotionListenerP might be registerd either by IID or + // name, unregister by both. + erP->RemoveEventListenerByIID(mMouseMotionListenerP, + NS_GET_IID(nsIDOMMouseMotionListener)); + + erP->RemoveEventListener(NS_LITERAL_STRING("mousemove"), + mMouseMotionListenerP, PR_TRUE); + } + + if (mResizeEventListenerP) + { + erP->RemoveEventListener(NS_LITERAL_STRING("resize"), + mResizeEventListenerP, PR_FALSE); + } } - return result; + + mMouseMotionListenerP = nsnull; + mResizeEventListenerP = nsnull; + + nsPlaintextEditor::RemoveEventListeners(); } NS_IMETHODIMP @@ -472,9 +415,7 @@ NS_IMETHODIMP nsHTMLEditor::BeginningOfDocument() return NS_ERROR_NOT_INITIALIZED; // get the root element - nsCOMPtr rootElement; - res = GetRootElement(getter_AddRefs(rootElement)); - if (NS_FAILED(res)) return res; + nsIDOMElement *rootElement = GetRoot(); if (!rootElement) return NS_ERROR_NULL_POINTER; // find first editable thingy @@ -1603,63 +1544,6 @@ NS_IMETHODIMP nsHTMLEditor::InsertBR(nsCOMPtr *outBRNode) return res; } -nsresult -nsHTMLEditor::GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver) -{ - if (!aEventReceiver) - return NS_ERROR_NULL_POINTER; - - *aEventReceiver = 0; - - nsCOMPtr rootElement; - - nsresult result = GetRootElement(getter_AddRefs(rootElement)); - - if (NS_FAILED(result)) - return result; - - if (!rootElement) - return NS_ERROR_FAILURE; - - // Now hack to make sure we are not anonymous content. - // If we are grab the parent of root element for our observer. - - nsCOMPtr content = do_QueryInterface(rootElement); - - if (content) - { - nsIContent* parent = content->GetParent(); - if (parent) - { - if (parent->IndexOf(content) < 0) - { - rootElement = do_QueryInterface(parent); //this will put listener on the form element basically - result = CallQueryInterface(rootElement, aEventReceiver); - } - else - rootElement = 0; // Let the event receiver work on the document instead of the root element - } - } - else - rootElement = 0; - - if (!rootElement && mDocWeak) - { - // Don't use getDocument here, because we have no way of knowing if - // Init() was ever called. So we need to get the document ourselves, - // if it exists. - - nsCOMPtr domdoc = do_QueryReferent(mDocWeak); - - if (!domdoc) - return NS_ERROR_FAILURE; - - result = domdoc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), (void **)aEventReceiver); - } - - return result; -} - nsresult nsHTMLEditor::CollapseSelectionToDeepestNonTableFirstChild(nsISelection *aSelection, nsIDOMNode *aNode) { @@ -1815,8 +1699,7 @@ nsHTMLEditor::RebuildDocumentFromSource(const nsAString& aSourceString) nsresult res = GetSelection(getter_AddRefs(selection)); if (NS_FAILED(res)) return res; - nsCOMPtr bodyElement; - res = GetRootElement(getter_AddRefs(bodyElement)); + nsIDOMElement *bodyElement = GetRoot(); if (NS_FAILED(res)) return res; if (!bodyElement) return NS_ERROR_NULL_POINTER; @@ -2476,7 +2359,6 @@ nsHTMLEditor::GetCSSBackgroundColorState(PRBool *aMixed, nsAString &aOutColor, P res = NodeIsBlockStatic(nodeToExamine, &isBlock); if (NS_FAILED(res)) return res; - nsCOMPtr htmlElement; nsCOMPtr tmp; if (aBlockLevel) { @@ -2488,15 +2370,15 @@ nsHTMLEditor::GetCSSBackgroundColorState(PRBool *aMixed, nsAString &aOutColor, P } do { // retrieve the computed style of background-color for blockParent - mHTMLCSSUtils->GetComputedProperty(blockParent, nsEditProperty::cssBackgroundColor, + mHTMLCSSUtils->GetComputedProperty(blockParent, + nsEditProperty::cssBackgroundColor, aOutColor); - tmp = blockParent; + tmp.swap(blockParent); res = tmp->GetParentNode(getter_AddRefs(blockParent)); - htmlElement = do_QueryInterface(tmp); // look at parent if the queried color is transparent and if the node to // examine is not the root of the document - } while ( aOutColor.EqualsLiteral("transparent") && htmlElement ); - if (!htmlElement && aOutColor.EqualsLiteral("transparent")) { + } while (aOutColor.EqualsLiteral("transparent") && blockParent); + if (aOutColor.EqualsLiteral("transparent")) { // we have hit the root of the document and the color is still transparent ! // Grumble... Let's look at the default background color because that's the // color we are looking for @@ -2529,11 +2411,10 @@ nsHTMLEditor::GetCSSBackgroundColorState(PRBool *aMixed, nsAString &aOutColor, P break; } } - res = nodeToExamine->GetParentNode(getter_AddRefs(tmp)); + tmp.swap(nodeToExamine); + res = tmp->GetParentNode(getter_AddRefs(nodeToExamine)); if (NS_FAILED(res)) return res; - nodeToExamine = tmp; - htmlElement = do_QueryInterface(tmp); - } while ( aOutColor.EqualsLiteral("transparent") && htmlElement ); + } while ( aOutColor.EqualsLiteral("transparent") && nodeToExamine ); } return NS_OK; } @@ -2578,8 +2459,7 @@ nsHTMLEditor::GetHTMLBackgroundColorState(PRBool *aMixed, nsAString &aOutColor) } // If no table or cell found, get page body - res = nsEditor::GetRootElement(getter_AddRefs(element)); - if (NS_FAILED(res)) return res; + element = GetRoot(); if (!element) return NS_ERROR_NULL_POINTER; return element->GetAttribute(styleName, aOutColor); @@ -3504,8 +3384,7 @@ nsHTMLEditor::SetHTMLBackgroundColor(const nsAString& aColor) // If we failed to find a cell, fall through to use originally-found element } else { // No table element -- set the background color on the body tag - res = nsEditor::GetRootElement(getter_AddRefs(element)); - if (NS_FAILED(res)) return res; + element = GetRoot(); if (!element) return NS_ERROR_NULL_POINTER; } // Use the editor method that goes through the transaction system @@ -3519,22 +3398,18 @@ nsHTMLEditor::SetHTMLBackgroundColor(const nsAString& aColor) NS_IMETHODIMP nsHTMLEditor::SetBodyAttribute(const nsAString& aAttribute, const nsAString& aValue) { - nsresult res; // TODO: Check selection for Cell, Row, Column or table and do color on appropriate level NS_ASSERTION(mDocWeak, "Missing Editor DOM Document"); // Set the background color attribute on the body tag - nsCOMPtr bodyElement; + nsIDOMElement *bodyElement = GetRoot(); - res = nsEditor::GetRootElement(getter_AddRefs(bodyElement)); - if (!bodyElement) res = NS_ERROR_NULL_POINTER; - if (NS_SUCCEEDED(res)) - { - // Use the editor method that goes through the transaction system - res = SetAttribute(bodyElement, aAttribute, aValue); - } - return res; + if (!bodyElement) + return NS_ERROR_NULL_POINTER; + + // Use the editor method that goes through the transaction system + return SetAttribute(bodyElement, aAttribute, aValue); } NS_IMETHODIMP @@ -4009,8 +3884,7 @@ nsCOMPtr nsHTMLEditor::FindUserSelectAllNode(nsIDOMNode *aNode) { nsCOMPtr resultNode; // starts out empty nsCOMPtr node = aNode; - nsCOMPtrroot; - GetRootElement(getter_AddRefs(root)); + nsIDOMElement *root = GetRoot(); if (!nsEditorUtils::IsDescendantOf(aNode, root)) return nsnull; @@ -4403,31 +4277,23 @@ nsHTMLEditor::TagCanContainTag(const nsAString& aParentTag, const nsAString& aCh NS_IMETHODIMP nsHTMLEditor::SelectEntireDocument(nsISelection *aSelection) { - nsresult res; if (!aSelection || !mRules) { return NS_ERROR_NULL_POINTER; } - // get body node - nsCOMPtrbodyElement; - res = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; - nsCOMPtrbodyNode = do_QueryInterface(bodyElement); - if (!bodyNode) return NS_ERROR_FAILURE; + // get editor root node + nsIDOMElement *rootElement = GetRoot(); // is doc empty? PRBool bDocIsEmpty; - res = mRules->DocumentIsEmpty(&bDocIsEmpty); + nsresult res = mRules->DocumentIsEmpty(&bDocIsEmpty); if (NS_FAILED(res)) return res; if (bDocIsEmpty) { // if its empty dont select entire doc - that would select the bogus node - return aSelection->Collapse(bodyNode, 0); + return aSelection->Collapse(rootElement, 0); } - else - { - return nsEditor::SelectEntireDocument(aSelection); - } - return res; + + return nsEditor::SelectEntireDocument(aSelection); } @@ -4525,10 +4391,10 @@ void nsHTMLEditor::IsTextPropertySetByContent(nsIDOMNode *aNode, nsCOMPtrtemp; result = node->GetParentNode(getter_AddRefs(temp)); if (NS_SUCCEEDED(result) && temp) { - node = do_QueryInterface(temp); + node = temp; } else { - node = do_QueryInterface(nsnull); + node = nsnull; } } } @@ -4718,17 +4584,6 @@ nsCOMPtr nsHTMLEditor::FindPreElement() } #endif /* PRE_NODE_IN_BODY */ -void nsHTMLEditor::HandleEventListenerError() -{ - // null out the nsCOMPtrs - mKeyListenerP = nsnull; - mMouseListenerP = nsnull; - mTextListenerP = nsnull; - mDragListenerP = nsnull; - mCompositionListenerP = nsnull; - mFocusListenerP = nsnull; -} - /* this method scans the selection for adjacent text nodes * and collapses them into a single text node. * "adjacent" means literally adjacent siblings of the same parent. @@ -4843,14 +4698,11 @@ nsHTMLEditor::GetNextElementByTagName(nsIDOMElement *aCurrentElement, NS_IMETHODIMP nsHTMLEditor::SetSelectionAtDocumentStart(nsISelection *aSelection) { - nsCOMPtr bodyElement; - nsresult res = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_SUCCEEDED(res)) - { - if (!bodyElement) return NS_ERROR_NULL_POINTER; - res = aSelection->Collapse(bodyElement,0); - } - return res; + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) + return NS_ERROR_NULL_POINTER; + + return aSelection->Collapse(rootElement,0); } #ifdef XP_MAC @@ -5061,7 +4913,7 @@ nsHTMLEditor::GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPt /////////////////////////////////////////////////////////////////////////// // GetPriorHTMLNode: returns the previous editable leaf node, if there is // one within the -// +// nsresult nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr *outNode, PRBool bNoBlockCrossing) { diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h index f31e70292fa..5b8a16ed305 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h @@ -327,10 +327,6 @@ public: /** Internal, static version */ static nsresult NodeIsBlockStatic(nsIDOMNode *aNode, PRBool *aIsBlock); - - /** we override this here to install event listeners */ - NS_IMETHOD PostCreate(); - NS_IMETHOD GetFlags(PRUint32 *aFlags); NS_IMETHOD SetFlags(PRUint32 aFlags); @@ -444,12 +440,10 @@ protected: NS_IMETHOD InitRules(); - /** install the event listeners for the editor - * used to be part of Init, but now broken out into a separate method - * called by PostCreate, giving the caller the chance to interpose - * their own listeners before we install our own backstops. - */ - NS_IMETHOD InstallEventListeners(); + // Create the event listeners for the editor to install + virtual nsresult CreateEventListeners(); + + virtual void RemoveEventListeners(); /** returns the layout object (nsIFrame in the real world) for aNode * @param aNode the content to get a frame for @@ -659,9 +653,6 @@ protected: PRInt32 aHighWaterMark); nsIDOMNode* GetArrayEndpoint(PRBool aEnd, nsCOMArray& aNodeArray); - /** simple utility to handle any error with event listener allocation or registration */ - void HandleEventListenerError(); - /* small utility routine to test if a break node is visible to user */ PRBool IsVisBreak(nsIDOMNode *aNode); @@ -746,8 +737,6 @@ protected: nsresult GetFirstEditableLeaf( nsIDOMNode *aNode, nsCOMPtr *aOutFirstLeaf); nsresult GetLastEditableLeaf( nsIDOMNode *aNode, nsCOMPtr *aOutLastLeaf); - nsresult GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver); - //XXX Kludge: Used to suppress spurious drag/drop events (bug 50703) PRBool mIgnoreSpuriousDragEvent; @@ -857,7 +846,6 @@ protected: nsCOMPtr mResizedObject; nsCOMPtr mMouseMotionListenerP; - nsCOMPtr mMutationListenerP; nsCOMPtr mSelectionListenerP; nsCOMPtr mResizeEventListenerP; diff --git a/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp index 8b7f65408bd..c0934d52b59 100644 --- a/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp @@ -72,9 +72,7 @@ nsHTMLEditor::ShowInlineTableEditingUI(nsIDOMElement * aCell) return NS_OK; // the resizers and the shadow will be anonymous children of the body - nsCOMPtr bodyElement; - nsresult res = nsEditor::GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; + nsIDOMElement *bodyElement = GetRoot(); if (!bodyElement) return NS_ERROR_NULL_POINTER; CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyElement, @@ -129,9 +127,7 @@ nsHTMLEditor::HideInlineTableEditingUI() // get the root content node. - nsCOMPtr bodyElement; - nsresult res = nsEditor::GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; + nsIDOMElement *bodyElement = GetRoot(); nsCOMPtr bodyContent( do_QueryInterface(bodyElement) ); if (!bodyContent) return NS_ERROR_FAILURE; diff --git a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp index ecafdcd9849..f8b8c9f6df5 100644 --- a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp @@ -336,12 +336,11 @@ nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement) mResizedObject = aResizedElement; // the resizers and the shadow will be anonymous children of the body - nsCOMPtr bodyElement; - nsresult res = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; + nsIDOMElement *bodyElement = GetRoot(); if (!bodyElement) return NS_ERROR_NULL_POINTER; // let's create the resizers + nsresult res; res = CreateResizer(getter_AddRefs(mTopLeftHandle), nsIHTMLObjectResizer::eTopLeft, bodyElement); if (NS_FAILED(res)) return res; @@ -409,7 +408,7 @@ nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement) if (!global) { return NS_ERROR_NULL_POINTER; } mResizeEventListenerP = new DocumentResizeEventListener(this); - if (!mResizeEventListenerP) { return NS_ERROR_NULL_POINTER; } + if (!mResizeEventListenerP) { return NS_ERROR_OUT_OF_MEMORY; } nsCOMPtr target = do_QueryInterface(global); res = target->AddEventListener(NS_LITERAL_STRING("resize"), mResizeEventListenerP, PR_FALSE); @@ -432,10 +431,7 @@ nsHTMLEditor::HideResizers(void) // get the root content node. - nsCOMPtr bodyElement; - nsresult res = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; - if (!bodyElement) return NS_ERROR_NULL_POINTER; + nsIDOMElement *bodyElement = GetRoot(); nsCOMPtr bodyContent( do_QueryInterface(bodyElement) ); if (!bodyContent) return NS_ERROR_FAILURE; @@ -463,10 +459,10 @@ nsHTMLEditor::HideResizers(void) // don't forget to remove the listeners ! - nsCOMPtr erP; - res = GetDOMEventReceiver(getter_AddRefs(erP)); + nsCOMPtr erP = GetDOMEventReceiver(); + nsresult res; - if (NS_SUCCEEDED(res) && erP && mMouseMotionListenerP) + if (erP && mMouseMotionListenerP) { res = erP->RemoveEventListener(NS_LITERAL_STRING("mousemove"), mMouseMotionListenerP, PR_TRUE); NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove mouse motion listener"); @@ -593,17 +589,17 @@ nsHTMLEditor::StartResizing(nsIDOMElement *aHandle) // add a mouse move listener to the editor if (!mMouseMotionListenerP) { mMouseMotionListenerP = new ResizerMouseMotionListener(this); - if (!mMouseMotionListenerP) {return NS_ERROR_NULL_POINTER;} - - nsCOMPtr erP; - result = GetDOMEventReceiver(getter_AddRefs(erP)); - if (NS_SUCCEEDED(result) && erP) - { - result = erP->AddEventListener(NS_LITERAL_STRING("mousemove"), mMouseMotionListenerP, PR_TRUE); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register mouse motion listener"); + if (!mMouseMotionListenerP) { + return NS_ERROR_OUT_OF_MEMORY; } - else - HandleEventListenerError(); + + nsCOMPtr erP = GetDOMEventReceiver(); + NS_ENSURE_TRUE(erP, NS_ERROR_FAILURE); + + result = erP->AddEventListener(NS_LITERAL_STRING("mousemove"), + mMouseMotionListenerP, PR_TRUE); + NS_ASSERTION(NS_SUCCEEDED(result), + "failed to register mouse motion listener"); } return result; } diff --git a/mozilla/editor/libeditor/text/nsPlaintextEditor.cpp b/mozilla/editor/libeditor/text/nsPlaintextEditor.cpp index 320cd37b993..6d3ea5f2b8f 100644 --- a/mozilla/editor/libeditor/text/nsPlaintextEditor.cpp +++ b/mozilla/editor/libeditor/text/nsPlaintextEditor.cpp @@ -105,14 +105,13 @@ nsPlaintextEditor::~nsPlaintextEditor() // Remove event listeners. Note that if we had an HTML editor, // it installed its own instead of these - nsCOMPtr erP; - nsresult result = GetDOMEventReceiver(getter_AddRefs(erP)); - if (NS_SUCCEEDED(result) && erP) + nsCOMPtr erP = GetDOMEventReceiver(); + if (erP) { nsCOMPtr dom3Targ(do_QueryInterface(erP)); nsCOMPtr sysGroup; if (NS_SUCCEEDED(erP->GetSystemEventGroup(getter_AddRefs(sysGroup)))) { - result = dom3Targ->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"), mKeyListenerP, PR_FALSE, sysGroup); + dom3Targ->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"), mKeyListenerP, PR_FALSE, sysGroup); } if (mMouseListenerP) { @@ -277,119 +276,46 @@ nsPlaintextEditor::SetDocumentCharacterSet(const nsACString & characterSet) return result; } -NS_IMETHODIMP -nsPlaintextEditor::PostCreate() +nsresult +nsPlaintextEditor::CreateEventListeners() { - nsresult result = InstallEventListeners(); - if (NS_FAILED(result)) return result; + nsresult rv = NS_OK; - return nsEditor::PostCreate(); -} - -NS_IMETHODIMP -nsPlaintextEditor::InstallEventListeners() -{ - NS_ASSERTION(mDocWeak, "no document set on this editor"); - if (!mDocWeak) return NS_ERROR_NOT_INITIALIZED; - - if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED; - - nsresult result; - // get a key listener - result = NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this); - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; - } - - // get a mouse listener - result = NS_NewEditorMouseListener(getter_AddRefs(mMouseListenerP), this); - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; + if (!mMouseListenerP) { + // get a mouse listener + rv |= NS_NewEditorMouseListener(getter_AddRefs(mMouseListenerP), this); } - // get a text listener - result = NS_NewEditorTextListener(getter_AddRefs(mTextListenerP),this); - if (NS_FAILED(result)) { -#ifdef DEBUG_TAGUE -printf("nsTextEditor.cpp: failed to get TextEvent Listener\n"); -#endif - HandleEventListenerError(); - return result; + if (!mKeyListenerP) { + // get a key listener + rv |= NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this); } - // get a composition listener - result = NS_NewEditorCompositionListener(getter_AddRefs(mCompositionListenerP),this); - if (NS_FAILED(result)) { -#ifdef DEBUG_TAGUE -printf("nsTextEditor.cpp: failed to get TextEvent Listener\n"); -#endif - HandleEventListenerError(); - return result; + if (!mTextListenerP) { + // get a text listener + rv |= NS_NewEditorTextListener(getter_AddRefs(mTextListenerP), this); } - // get a drag listener - nsCOMPtr presShell = do_QueryReferent(mPresShellWeak); - result = NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), presShell, this); - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; + if (!mCompositionListenerP) { + // get a composition listener + rv |= + NS_NewEditorCompositionListener(getter_AddRefs(mCompositionListenerP), + this); } - // get a focus listener - result = NS_NewEditorFocusListener(getter_AddRefs(mFocusListenerP), this); - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; + if (!mDragListenerP) { + // get a drag listener + nsCOMPtr presShell = do_QueryReferent(mPresShellWeak); + rv |= NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), presShell, + this); } - nsCOMPtr erP; - result = GetDOMEventReceiver(getter_AddRefs(erP)); - - //end hack - if (NS_FAILED(result)) { - HandleEventListenerError(); - return result; + if (!mFocusListenerP) { + // get a focus listener + rv |= NS_NewEditorFocusListener(getter_AddRefs(mFocusListenerP), this); } - // register the event listeners with the DOM event reveiver - nsCOMPtr dom3Targ(do_QueryInterface(erP)); - nsCOMPtr sysGroup; - if (NS_SUCCEEDED(erP->GetSystemEventGroup(getter_AddRefs(sysGroup)))) { - result = dom3Targ->AddGroupedEventListener(NS_LITERAL_STRING("keypress"), mKeyListenerP, PR_FALSE, sysGroup); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register key listener in system group"); - } - - if (NS_SUCCEEDED(result)) - { - result = erP->AddEventListenerByIID(mMouseListenerP, NS_GET_IID(nsIDOMMouseListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register mouse listener"); - if (NS_SUCCEEDED(result)) - { - result = erP->AddEventListenerByIID(mFocusListenerP, NS_GET_IID(nsIDOMFocusListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register focus listener"); - if (NS_SUCCEEDED(result)) - { - result = erP->AddEventListenerByIID(mTextListenerP, NS_GET_IID(nsIDOMTextListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register text listener"); - if (NS_SUCCEEDED(result)) - { - result = erP->AddEventListenerByIID(mCompositionListenerP, NS_GET_IID(nsIDOMCompositionListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register composition listener"); - if (NS_SUCCEEDED(result)) - { - result = erP->AddEventListenerByIID(mDragListenerP, NS_GET_IID(nsIDOMDragListener)); - NS_ASSERTION(NS_SUCCEEDED(result), "failed to register drag listener"); - } - } - } - } - } - if (NS_FAILED(result)) { - HandleEventListenerError(); - } - return result; + return rv; } NS_IMETHODIMP @@ -738,59 +664,6 @@ nsPlaintextEditor::GetAbsoluteOffsetsForPoints(nsIDOMNode *aInStartNode, return result; } -nsresult -nsPlaintextEditor::GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver) -{ - if (!aEventReceiver) - return NS_ERROR_NULL_POINTER; - - *aEventReceiver = 0; - - nsCOMPtr rootElement; - nsresult result = GetRootElement(getter_AddRefs(rootElement)); - if (NS_FAILED(result)) - return result; - - if (!rootElement) - return NS_ERROR_FAILURE; - - // Now hack to make sure we are not anonymous content. - // If we are grab the parent of root element for our observer. - - nsCOMPtr content = do_QueryInterface(rootElement); - if (content) - { - nsCOMPtr parent = content->GetParent(); - if (parent) - { - if (parent->IndexOf(content) < 0 ) - { - rootElement = do_QueryInterface(parent); //this will put listener on the form element basically - result = CallQueryInterface(rootElement, aEventReceiver); - } - else - rootElement = 0; // Let the event receiver work on the document instead of the root element - } - } - else - rootElement = 0; - - if (!rootElement && mDocWeak) - { - // Don't use getDocument here, because we have no way of knowing if - // Init() was ever called. So we need to get the document ourselves, - // if it exists. - - nsCOMPtr domdoc = do_QueryReferent(mDocWeak); - if (!domdoc) - return NS_ERROR_FAILURE; - - result = domdoc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), (void **)aEventReceiver); - } - - return result; -} - NS_IMETHODIMP nsPlaintextEditor::DeleteSelection(nsIEditor::EDirection aAction) { if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } @@ -1051,26 +924,27 @@ nsPlaintextEditor::GetTextLength(PRInt32 *aCount) if (docEmpty) return NS_OK; - // get the body node - nsCOMPtr bodyElement; - result = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(result)) { return result; } - if (!bodyElement) { return NS_ERROR_NULL_POINTER; } + // get the root node + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) + { + return NS_ERROR_NULL_POINTER; + } // get the offsets of the first and last children of the body node nsCOMPtrlastChild; - result = bodyElement->GetLastChild(getter_AddRefs(lastChild)); + result = rootElement->GetLastChild(getter_AddRefs(lastChild)); if (NS_FAILED(result)) { return result; } if (!lastChild) { return NS_ERROR_NULL_POINTER; } PRInt32 numBodyChildren = 0; - result = GetChildOffset(lastChild, bodyElement, numBodyChildren); + result = GetChildOffset(lastChild, rootElement, numBodyChildren); if (NS_FAILED(result)) { return result; } // count PRInt32 start, end; - result = GetAbsoluteOffsetsForPoints(bodyElement, 0, - bodyElement, numBodyChildren, - bodyElement, start, end); + result = GetAbsoluteOffsetsForPoints(rootElement, 0, + rootElement, numBodyChildren, + rootElement, start, end); if (NS_SUCCEEDED(result)) { NS_ASSERTION(0==start, "GetAbsoluteOffsetsForPoints failed to set start correctly."); @@ -1146,15 +1020,14 @@ nsPlaintextEditor::SetWrapWidth(PRInt32 aWrapColumn) // Ought to set a style sheet here ... // Probably should keep around an mPlaintextStyleSheet for this purpose. - nsCOMPtr bodyElement; - nsresult res = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; - if (!bodyElement) return NS_ERROR_NULL_POINTER; + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) + return NS_ERROR_NULL_POINTER; - // Get the current style for this body element: + // Get the current style for this root element: NS_NAMED_LITERAL_STRING(styleName, "style"); nsAutoString styleValue; - res = bodyElement->GetAttribute(styleName, styleValue); + nsresult res = rootElement->GetAttribute(styleName, styleValue); if (NS_FAILED(res)) return res; // We'll replace styles for these values: @@ -1202,7 +1075,7 @@ nsPlaintextEditor::SetWrapWidth(PRInt32 aWrapColumn) else styleValue.AppendLiteral("white-space: pre;"); - return bodyElement->SetAttribute(styleName, styleValue); + return rootElement->SetAttribute(styleName, styleValue); } @@ -1359,8 +1232,7 @@ nsPlaintextEditor::GetAndInitDocEncoder(const nsAString& aFormatType, // in which case we set the selection to encompass the root. else { - nsCOMPtr rootElement; - GetRootElement(getter_AddRefs(rootElement)); + nsIDOMElement *rootElement = GetRoot(); NS_ENSURE_TRUE(rootElement, NS_ERROR_FAILURE); if (!nsTextEditUtils::IsBody(rootElement)) { @@ -1880,19 +1752,18 @@ NS_IMETHODIMP nsPlaintextEditor::SelectEntireDocument(nsISelection *aSelection) { if (!aSelection || !mRules) { return NS_ERROR_NULL_POINTER; } - + // is doc empty? PRBool bDocIsEmpty; if (NS_SUCCEEDED(mRules->DocumentIsEmpty(&bDocIsEmpty)) && bDocIsEmpty) { - // get body node - nsCOMPtrbodyElement; - nsresult res = GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; - if (!bodyElement) return NS_ERROR_FAILURE; + // get root node + nsIDOMElement *rootElement = GetRoot(); + if (!rootElement) + return NS_ERROR_FAILURE; // if it's empty don't select entire doc - that would select the bogus node - return aSelection->Collapse(bodyElement, 0); + return aSelection->Collapse(rootElement, 0); } return nsEditor::SelectEntireDocument(aSelection); @@ -1931,21 +1802,6 @@ NS_IMETHODIMP nsPlaintextEditor::GetLayoutObject(nsIDOMNode *aNode, nsISupports #pragma mark - #endif -void nsPlaintextEditor::HandleEventListenerError() -{ - // null out the nsCOMPtrs - mKeyListenerP = nsnull; - mMouseListenerP = nsnull; - mTextListenerP = nsnull; - mDragListenerP = nsnull; - mCompositionListenerP = nsnull; - mFocusListenerP = nsnull; -} - -#ifdef XP_MAC -#pragma mark - -#endif - nsresult nsPlaintextEditor::SetAttributeOrEquivalent(nsIDOMElement * aElement, const nsAString & aAttribute, diff --git a/mozilla/editor/libeditor/text/nsPlaintextEditor.h b/mozilla/editor/libeditor/text/nsPlaintextEditor.h index 406c890751b..2faf3be9505 100644 --- a/mozilla/editor/libeditor/text/nsPlaintextEditor.h +++ b/mozilla/editor/libeditor/text/nsPlaintextEditor.h @@ -111,9 +111,6 @@ public: NS_IMETHOD SetDocumentCharacterSet(const nsACString & characterSet); - /** we override this here to install event listeners */ - NS_IMETHOD PostCreate(); - NS_IMETHOD GetFlags(PRUint32 *aFlags); NS_IMETHOD SetFlags(PRUint32 aFlags); @@ -180,13 +177,9 @@ protected: NS_IMETHOD InitRules(); void BeginEditorInit(); nsresult EndEditorInit(); - - /** install the event listeners for the editor - * used to be part of Init, but now broken out into a separate method - * called by PostCreate, giving the caller the chance to interpose - * their own listeners before we install our own backstops. - */ - NS_IMETHOD InstallEventListeners(); + + // Create the event listeners for the editor to install. + virtual nsresult CreateEventListeners(); /** returns the layout object (nsIFrame in the real world) for aNode * @param aNode the content to get a frame for @@ -222,14 +215,9 @@ protected: /** shared outputstring; returns whether selection is collapsed and resulting string */ nsresult SharedOutputString(PRUint32 aFlags, PRBool* aIsCollapsed, nsAString& aResult); - /** simple utility to handle any error with event listener allocation or registration */ - void HandleEventListenerError(); - /* small utility routine to test the eEditorReadonly bit */ PRBool IsModifiable(); - nsresult GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver); - //XXX Kludge: Used to suppress spurious drag/drop events (bug 50703) PRBool mIgnoreSpuriousDragEvent; NS_IMETHOD IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent) {mIgnoreSpuriousDragEvent = aIgnoreSpuriousDragEvent; return NS_OK;} @@ -238,12 +226,6 @@ protected: protected: nsCOMPtr mRules; - nsCOMPtr mKeyListenerP; - nsCOMPtr mMouseListenerP; - nsCOMPtr mTextListenerP; - nsCOMPtr mCompositionListenerP; - nsCOMPtr mDragListenerP; - nsCOMPtr mFocusListenerP; PRBool mWrapToWindow; PRInt32 mWrapColumn; PRInt32 mMaxTextLength; diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.cpp b/mozilla/editor/libeditor/text/nsTextEditRules.cpp index 3ca5dd261c6..641211c5709 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.cpp +++ b/mozilla/editor/libeditor/text/nsTextEditRules.cpp @@ -93,8 +93,6 @@ nsTextEditRules::nsTextEditRules() , mPasswordText() , mPasswordIMEText() , mPasswordIMEIndex(0) -, mBogusNode(nsnull) -, mBody(nsnull) , mFlags(0) // initialized to 0 ("no flags set"). Real initial value is given in Init() , mActionNesting(0) , mLockRulesSniffing(PR_FALSE) @@ -131,16 +129,12 @@ nsTextEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags) mEditor->GetSelection(getter_AddRefs(selection)); NS_ASSERTION(selection, "editor cannot get selection"); - // remember our root node - nsCOMPtr bodyElement; - nsresult res = mEditor->GetRootElement(getter_AddRefs(bodyElement)); - if (NS_FAILED(res)) return res; - if (!bodyElement) return NS_ERROR_NULL_POINTER; - mBody = do_QueryInterface(bodyElement); - if (!mBody) return NS_ERROR_FAILURE; + // Cache our body node, if available. + GetBody(); - // put in a magic br if needed - res = CreateBogusNodeIfNeeded(selection); // this method handles null selection, which should never happen anyway + // Put in a magic br if needed. This method handles null selection, + // which should never happen anyway + nsresult res = CreateBogusNodeIfNeeded(selection); if (NS_FAILED(res)) return res; if (mFlags & nsIPlaintextEditor::eEditorPlaintextMask) @@ -149,25 +143,31 @@ nsTextEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags) res = CreateTrailingBRIfNeeded(); if (NS_FAILED(res)) return res; } - - // create a range that is the entire body contents - nsCOMPtr wholeDoc = do_CreateInstance("@mozilla.org/content/range;1"); - if (!wholeDoc) return NS_ERROR_NULL_POINTER; - wholeDoc->SetStart(mBody,0); - nsCOMPtr list; - res = mBody->GetChildNodes(getter_AddRefs(list)); - if (NS_FAILED(res)) return res; - if (!list) return NS_ERROR_FAILURE; - PRUint32 listCount; - res = list->GetLength(&listCount); - if (NS_FAILED(res)) return res; + if (mBody) + { + // create a range that is the entire body contents + nsCOMPtr wholeDoc = + do_CreateInstance("@mozilla.org/content/range;1"); + if (!wholeDoc) return NS_ERROR_NULL_POINTER; + wholeDoc->SetStart(mBody,0); + nsCOMPtr list; + res = mBody->GetChildNodes(getter_AddRefs(list)); + if (NS_FAILED(res)) return res; + if (!list) return NS_ERROR_FAILURE; - res = wholeDoc->SetEnd(mBody, listCount); - if (NS_FAILED(res)) return res; + PRUint32 listCount; + res = list->GetLength(&listCount); + if (NS_FAILED(res)) return res; - // replace newlines in that range with breaks - return ReplaceNewlines(wholeDoc); + res = wholeDoc->SetEnd(mBody, listCount); + if (NS_FAILED(res)) return res; + + // replace newlines in that range with breaks + res = ReplaceNewlines(wholeDoc); + } + + return res; } NS_IMETHODIMP @@ -368,7 +368,7 @@ nsTextEditRules::DocumentIsEmpty(PRBool *aDocumentIsEmpty) if (!aDocumentIsEmpty) return NS_ERROR_NULL_POINTER; - *aDocumentIsEmpty = (mBogusNode.get() != nsnull); + *aDocumentIsEmpty = (mBogusNode != nsnull); return NS_OK; } @@ -392,7 +392,7 @@ nsTextEditRules::WillInsert(nsISelection *aSelection, PRBool *aCancel) if (mBogusNode) { mEditor->DeleteNode(mBogusNode); - mBogusNode = do_QueryInterface(nsnull); + mBogusNode = nsnull; } return NS_OK; @@ -455,9 +455,7 @@ nsTextEditRules::DidInsertBreak(nsISelection *aSelection, nsresult aResult) if (NS_FAILED(res)) return res; // confirm we are at end of document if (selOffset == 0) return NS_OK; // cant be after a br if we are at offset 0 - nsCOMPtr rootElem; - res = mEditor->GetRootElement(getter_AddRefs(rootElem)); - if (NS_FAILED(res)) return res; + nsIDOMElement *rootElem = mEditor->GetRoot(); nsCOMPtr root = do_QueryInterface(rootElem); if (!root) return NS_ERROR_NULL_POINTER; @@ -950,7 +948,7 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection, // make sure it is not last node in editfield. If it is, cancel deletion. if (nextNode && (aCollapsedAction == nsIEditor::eNext) && nsTextEditUtils::IsBreak(nextNode)) { - if (!mBody) return NS_ERROR_NULL_POINTER; + if (!GetBody()) return NS_ERROR_NULL_POINTER; nsCOMPtr lastChild; res = mBody->GetLastChild(getter_AddRefs(lastChild)); if (lastChild == nextNode) @@ -1025,17 +1023,15 @@ nsTextEditRules:: DidUndo(nsISelection *aSelection, nsresult aResult) if (NS_SUCCEEDED(res)) { if (mBogusNode) { - mBogusNode = do_QueryInterface(nsnull); + mBogusNode = nsnull; } else { - nsCOMPtr theBody; - res = mEditor->GetRootElement(getter_AddRefs(theBody)); - if (NS_FAILED(res)) return res; - if (!theBody) return NS_ERROR_FAILURE; - nsCOMPtr node = mEditor->GetLeftmostChild(theBody); + nsIDOMElement *theRoot = mEditor->GetRoot(); + if (!theRoot) return NS_ERROR_FAILURE; + nsCOMPtr node = mEditor->GetLeftmostChild(theRoot); if (node && mEditor->IsMozEditorBogusNode(node)) - mBogusNode = do_QueryInterface(node); + mBogusNode = node; } } return res; @@ -1060,17 +1056,16 @@ nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult) if (NS_SUCCEEDED(res)) { if (mBogusNode) { - mBogusNode = do_QueryInterface(nsnull); + mBogusNode = nsnull; } else { - nsCOMPtr theBody; - res = mEditor->GetRootElement(getter_AddRefs(theBody)); - if (NS_FAILED(res)) return res; - if (!theBody) return NS_ERROR_FAILURE; + nsIDOMElement *theRoot = mEditor->GetRoot(); + if (!theRoot) return NS_ERROR_FAILURE; nsCOMPtr nodeList; - res = theBody->GetElementsByTagName(NS_LITERAL_STRING("div"), getter_AddRefs(nodeList)); + res = theRoot->GetElementsByTagName(NS_LITERAL_STRING("div"), + getter_AddRefs(nodeList)); if (NS_FAILED(res)) return res; if (nodeList) { @@ -1078,11 +1073,11 @@ nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult) nodeList->GetLength(&len); if (len != 1) return NS_OK; // only in the case of one div could there be the bogus node - nsCOMPtrnode; + nsCOMPtr node; nodeList->Item(0, getter_AddRefs(node)); if (!node) return NS_ERROR_NULL_POINTER; if (mEditor->IsMozEditorBogusNode(node)) - mBogusNode = do_QueryInterface(node); + mBogusNode = node; } } } @@ -1213,7 +1208,7 @@ nsTextEditRules::CreateTrailingBRIfNeeded() // but only if we aren't a single line edit field if (mFlags & nsIPlaintextEditor::eEditorSingleLineMask) return NS_OK; - if (!mBody) return NS_ERROR_NULL_POINTER; + if (!GetBody()) return NS_ERROR_NULL_POINTER; nsCOMPtr lastChild; nsresult res = mBody->GetLastChild(getter_AddRefs(lastChild)); // assuming CreateBogusNodeIfNeeded() has been called first @@ -1242,13 +1237,19 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection) // tell rules system to not do any post-processing nsAutoRules beginRulesSniffing(mEditor, nsEditor::kOpIgnore, nsIEditor::eNone); - if (!mBody) return NS_ERROR_NULL_POINTER; + if (!GetBody()) + { + // we don't even have a body yet, don't insert any bogus nodes at + // this point. + + return NS_OK; + } // now we've got the body tag. // iterate the body tag, looking for editable content // if no editable content is found, insert the bogus node PRBool needsBogusContent=PR_TRUE; - nsCOMPtrbodyChild; + nsCOMPtr bodyChild; nsresult res = mBody->GetFirstChild(getter_AddRefs(bodyChild)); while ((NS_SUCCEEDED(res)) && bodyChild) { @@ -1270,7 +1271,7 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection) nsCOMPtrbrElement = do_QueryInterface(newContent); // set mBogusNode to be the newly created
- mBogusNode = do_QueryInterface(brElement); + mBogusNode = brElement; if (!mBogusNode) return NS_ERROR_NULL_POINTER; // give it a special attribute @@ -1412,3 +1413,15 @@ nsTextEditRules::CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtrGetRoot(); + } + + return mBody; +} diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.h b/mozilla/editor/libeditor/text/nsTextEditRules.h index d5a78a6ecd1..71e6eca430e 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.h +++ b/mozilla/editor/libeditor/text/nsTextEditRules.h @@ -170,7 +170,7 @@ protected: nsresult ReplaceNewlines(nsIDOMRange *aRange); /** creates a trailing break in the text doc if there is not one already */ - nsresult CreateTrailingBRIfNeeded(); + nsresult CreateTrailingBRIfNeeded(); /** creates a bogus text node if the document has no editable content */ nsresult CreateBogusNodeIfNeeded(nsISelection *aSelection); @@ -196,6 +196,8 @@ protected: nsIEditor::EDirection aAction, PRBool *aCancel); + nsIDOMNode *GetBody(); + // data members nsPlaintextEditor *mEditor; // note that we do not refcount the editor nsString mPasswordText; // a buffer we use to store the real value of password editors diff --git a/mozilla/editor/libeditor/text/nsTextEditUtils.cpp b/mozilla/editor/libeditor/text/nsTextEditUtils.cpp index e5b4d55806d..ffbaca6ce46 100644 --- a/mozilla/editor/libeditor/text/nsTextEditUtils.cpp +++ b/mozilla/editor/libeditor/text/nsTextEditUtils.cpp @@ -104,17 +104,17 @@ nsTextEditUtils::HasMozAttr(nsIDOMNode *node) PRBool nsTextEditUtils::InBody(nsIDOMNode *node, nsIEditor *editor) { - if ( node ) + if (node) { - nsCOMPtr bodyElement; - nsresult res = editor->GetRootElement(getter_AddRefs(bodyElement)); + nsCOMPtr rootElement; + nsresult res = editor->GetRootElement(getter_AddRefs(rootElement)); if (NS_FAILED(res)) return res; - nsCOMPtr bodyNode = do_QueryInterface(bodyElement); - if (!bodyNode) return NS_ERROR_NULL_POINTER; + nsCOMPtr rootNode = do_QueryInterface(rootElement); + if (!rootNode) return NS_ERROR_NULL_POINTER; nsCOMPtr tmp; nsCOMPtr p = node; - while (p && p!= bodyNode) + while (p && p != rootNode) { if (NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp) return PR_FALSE;