diff --git a/editor/base/nsEditor.cpp b/editor/base/nsEditor.cpp index 3579aef41afe..fa498408d775 100644 --- a/editor/base/nsEditor.cpp +++ b/editor/base/nsEditor.cpp @@ -827,7 +827,7 @@ NS_IMPL_QUERY_INTERFACE3(nsEditor, nsIEditor, nsIEditorIMESupport, nsISupportsWe NS_IMETHODIMP -nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsISelectionController *aSelCon, PRUint32 aFlags) +nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags) { NS_PRECONDITION(nsnull!=aDoc && nsnull!=aPresShell, "bad arg"); if ((nsnull==aDoc) || (nsnull==aPresShell)) @@ -840,6 +840,10 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsISelectionContr nsCOMPtr ps = do_QueryReferent(mPresShellWeak); if (!ps) return NS_ERROR_NOT_INITIALIZED; + //set up body element if we are passed one. + if (aRoot) + mBodyElement = do_QueryInterface(aRoot); + // disable links nsCOMPtr context; ps->GetPresContext(getter_AddRefs(context)); @@ -2342,7 +2346,7 @@ nsEditor::ForceCompositionEnd() // 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::GetBodyElement(nsIDOMElement **aBodyElement) +nsEditor::GetRootElement(nsIDOMElement **aBodyElement) { nsresult result = NS_OK; @@ -2645,7 +2649,7 @@ NS_IMETHODIMP nsEditor::SelectEntireDocument(nsIDOMSelection *aSelection) nsresult result; if (!aSelection) { return NS_ERROR_NULL_POINTER; } nsCOMPtrbodyElement; - result = GetBodyElement(getter_AddRefs(bodyElement)); + result = GetRootElement(getter_AddRefs(bodyElement)); if ((NS_SUCCEEDED(result)) && bodyElement) { nsCOMPtrbodyNode = do_QueryInterface(bodyElement); diff --git a/editor/base/nsEditor.h b/editor/base/nsEditor.h index ddf12e66c7f9..a0e87535a775 100644 --- a/editor/base/nsEditor.h +++ b/editor/base/nsEditor.h @@ -189,11 +189,12 @@ public: NS_DECL_ISUPPORTS /* ------------ nsIEditor methods -------------- */ - NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell, nsISelectionController *aSelCon, PRUint32 aFlags); + NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell, nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags); NS_IMETHOD PostCreate(); NS_IMETHOD GetFlags(PRUint32 *aFlags) = 0; NS_IMETHOD SetFlags(PRUint32 aFlags) = 0; NS_IMETHOD GetDocument(nsIDOMDocument **aDoc); + NS_IMETHOD GetRootElement(nsIDOMElement **aElement); NS_IMETHOD GetPresShell(nsIPresShell **aPS); NS_IMETHOD GetSelectionController(nsISelectionController **aSel); NS_IMETHOD GetSelection(nsIDOMSelection **aSelection); @@ -460,10 +461,6 @@ protected: public: - /** return the body element */ - /** It would make more sense for this to be in nsHTMLEditor, no? */ - NS_IMETHOD GetBodyElement(nsIDOMElement **aElement); - /** All editor operations which alter the doc should be prefaced * with a call to StartOperation, naming the action and direction */ NS_IMETHOD StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection); diff --git a/editor/base/nsEditorShell.cpp b/editor/base/nsEditorShell.cpp index e7ac4124105d..40631fdfc1e7 100644 --- a/editor/base/nsEditorShell.cpp +++ b/editor/base/nsEditorShell.cpp @@ -662,17 +662,17 @@ nsEditorShell::InstantiateEditor(nsIDOMDocument *aDoc, nsIPresShell *aPresShell) { if (mEditorTypeString.EqualsWithConversion("text")) { - err = editor->Init(aDoc, aPresShell, selCon, nsIHTMLEditor::eEditorPlaintextMask); + err = editor->Init(aDoc, aPresShell, nsnull, selCon, nsIHTMLEditor::eEditorPlaintextMask); mEditorType = ePlainTextEditorType; } else if (mEditorTypeString.EqualsWithConversion("html") || mEditorTypeString.IsEmpty()) // empty string default to HTML editor { - err = editor->Init(aDoc, aPresShell, selCon, 0); + err = editor->Init(aDoc, aPresShell, nsnull, selCon, 0); mEditorType = eHTMLTextEditorType; } else if (mEditorTypeString.EqualsWithConversion("htmlmail")) // HTML editor with special mail rules { - err = editor->Init(aDoc, aPresShell, selCon, nsIHTMLEditor::eEditorMailMask); + err = editor->Init(aDoc, aPresShell, nsnull, selCon, nsIHTMLEditor::eEditorMailMask); mEditorType = eHTMLTextEditorType; } else diff --git a/editor/base/nsHTMLEditRules.cpp b/editor/base/nsHTMLEditRules.cpp index 5e95fd27b430..6b1d768dac5f 100644 --- a/editor/base/nsHTMLEditRules.cpp +++ b/editor/base/nsHTMLEditRules.cpp @@ -126,7 +126,7 @@ nsHTMLEditRules::Init(nsHTMLEditor *aEditor, PRUint32 aFlags) // set up mDocChangeRange to be whole doc nsCOMPtr bodyElem; nsCOMPtr bodyNode; - mEditor->GetBodyElement(getter_AddRefs(bodyElem)); + mEditor->GetRootElement(getter_AddRefs(bodyElem)); bodyNode = do_QueryInterface(bodyElem); if (bodyNode) { @@ -857,7 +857,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, if (NS_FAILED(res)) return res; // if there is no next node, or it's not in the body, then cancel the deletion - if (!nextNode || !nsHTMLEditUtils::InBody(nextNode)) + if (!nextNode || !nsHTMLEditUtils::InBody(nextNode, mEditor)) { *aCancel = PR_TRUE; return res; @@ -4461,7 +4461,7 @@ nsHTMLEditRules::ConfirmSelectionInBody() nsCOMPtr bodyNode; // get the body - res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); + res = mEditor->GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; if (!bodyElement) return NS_ERROR_UNEXPECTED; bodyNode = do_QueryInterface(bodyElement); diff --git a/editor/base/nsHTMLEditRules.h b/editor/base/nsHTMLEditRules.h index 6c038fd56547..478fbd7a1e5c 100644 --- a/editor/base/nsHTMLEditRules.h +++ b/editor/base/nsHTMLEditRules.h @@ -33,6 +33,7 @@ class nsISupportsArray; class nsVoidArray; class nsIDOMElement; +class nsIEditor; class nsHTMLEditRules : public nsIHTMLEditRules, nsTextEditRules, nsIEditActionListener { diff --git a/editor/base/nsHTMLEditUtils.cpp b/editor/base/nsHTMLEditUtils.cpp index 80fb72b93b7a..d57310c355bb 100644 --- a/editor/base/nsHTMLEditUtils.cpp +++ b/editor/base/nsHTMLEditUtils.cpp @@ -143,20 +143,25 @@ nsHTMLEditUtils::HasMozAttr(nsIDOMNode *node) // InBody: true if node is a descendant of the body // PRBool -nsHTMLEditUtils::InBody(nsIDOMNode *node) +nsHTMLEditUtils::InBody(nsIDOMNode *node, nsIEditor *editor) { - NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::InBody"); - nsCOMPtr tmp; - nsCOMPtr p = do_QueryInterface(node); - - while (p && !IsBody(p)) + if ( node ) { - if ( NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp) // no parent, ran off top of tree - return PR_FALSE; - p = tmp; + nsCOMPtr bodyElement; + nsresult res = editor->GetRootElement(getter_AddRefs(bodyElement)); + if (NS_FAILED(res) || !bodyElement) + return res?res:NS_ERROR_NULL_POINTER; + nsCOMPtr bodyNode = do_QueryInterface(bodyElement); + nsCOMPtr tmp; + nsCOMPtr p = node; + while (p && p!= bodyNode) + { + if (NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp) + return PR_FALSE; + p = tmp; + } } - if (p) return PR_TRUE; - return PR_FALSE; + return PR_TRUE; } diff --git a/editor/base/nsHTMLEditUtils.h b/editor/base/nsHTMLEditUtils.h index 16d3046584de..e956cbf16c63 100644 --- a/editor/base/nsHTMLEditUtils.h +++ b/editor/base/nsHTMLEditUtils.h @@ -25,7 +25,7 @@ #include "prtypes.h" // for PRBool #include "nsError.h" // for nsresult - +class nsIEditor; class nsIDOMNode; class nsHTMLEditUtils @@ -38,7 +38,7 @@ public: static PRBool IsSmall(nsIDOMNode *aNode); static PRBool IsMozBR(nsIDOMNode *aNode); static PRBool HasMozAttr(nsIDOMNode *aNode); - static PRBool InBody(nsIDOMNode *aNode); + static PRBool InBody(nsIDOMNode *aNode, nsIEditor *aEditor); // from nsHTMLEditRules: static PRBool IsHeader(nsIDOMNode *aNode); diff --git a/editor/base/nsHTMLEditor.cpp b/editor/base/nsHTMLEditor.cpp index 3b4d0c819be8..aed62ff2f160 100644 --- a/editor/base/nsHTMLEditor.cpp +++ b/editor/base/nsHTMLEditor.cpp @@ -380,7 +380,7 @@ NS_IMETHODIMP nsHTMLEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr) NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, - nsIPresShell *aPresShell, nsISelectionController *aSelCon, PRUint32 aFlags) + nsIPresShell *aPresShell, nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags) { NS_PRECONDITION(aDoc && aPresShell, "bad arg"); if (!aDoc || !aPresShell) @@ -388,11 +388,11 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, nsresult result = NS_ERROR_NULL_POINTER; // Init the base editor - result = nsEditor::Init(aDoc, aPresShell, aSelCon, aFlags); + result = nsEditor::Init(aDoc, aPresShell, aRoot, aSelCon, aFlags); if (NS_FAILED(result)) { return result; } nsCOMPtr bodyElement; - result = nsEditor::GetBodyElement(getter_AddRefs(bodyElement)); + result = nsEditor::GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(result)) { return result; } if (!bodyElement) { return NS_ERROR_NULL_POINTER; } @@ -585,10 +585,32 @@ printf("nsTextEditor.cpp: failed to get TextEvent Listener\n"); } // get the DOM event receiver + nsCOMPtr domdoc; + nsEditor::GetDocument(getter_AddRefs(domdoc)); nsCOMPtr erP; - nsCOMPtr doc = do_QueryReferent(mDocWeak); - if (!doc) return NS_ERROR_NOT_INITIALIZED; - result = doc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + nsCOMPtr rootElement; + GetRootElement(getter_AddRefs(rootElement)); + //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; + if (NS_SUCCEEDED(content->GetParent(*getter_AddRefs(parent))) && parent) + { + PRInt32 index; + if (NS_FAILED(parent->IndexOf(content, index)) || index<0 ) + { + rootElement = do_QueryInterface(parent); + result = rootElement->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + } + else + rootElement = 0; + } + } + if (!rootElement && domdoc) + result = domdoc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + //end hack if (NS_FAILED(result)) { HandleEventListenerError(); return result; @@ -3625,7 +3647,7 @@ nsHTMLEditor::SetBackgroundColor(const nsString& 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::GetBodyElement(getter_AddRefs(element)); + res = nsEditor::GetRootElement(getter_AddRefs(element)); if (NS_FAILED(res)) return res; if (!element) return NS_ERROR_NULL_POINTER; } @@ -3643,7 +3665,7 @@ NS_IMETHODIMP nsHTMLEditor::SetBodyAttribute(const nsString& aAttribute, const n // Set the background color attribute on the body tag nsCOMPtr bodyElement; - res = nsEditor::GetBodyElement(getter_AddRefs(bodyElement)); + res = nsEditor::GetRootElement(getter_AddRefs(bodyElement)); if (!bodyElement) res = NS_ERROR_NULL_POINTER; if (NS_SUCCEEDED(res)) { @@ -3734,7 +3756,7 @@ nsHTMLEditor::GetDocumentLength(PRInt32 *aCount) // get the body node nsCOMPtr bodyElement; - result = nsEditor::GetBodyElement(getter_AddRefs(bodyElement)); + result = nsEditor::GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(result)) { return result; } if (!bodyElement) { return NS_ERROR_NULL_POINTER; } @@ -3957,7 +3979,7 @@ NS_IMETHODIMP nsHTMLEditor::GetBodyStyleContext(nsIStyleContext** aStyleContext) { nsCOMPtr body; - nsresult res = GetBodyElement(getter_AddRefs(body)); + nsresult res = GetRootElement(getter_AddRefs(body)); if (NS_FAILED(res)) return res; nsCOMPtr content = do_QueryInterface(body); @@ -4044,7 +4066,7 @@ NS_IMETHODIMP nsHTMLEditor::SetBodyWrapWidth(PRInt32 aWrapColumn) // Ought to set a style sheet here ... // Probably should keep around an mPlaintextStyleSheet for this purpose. nsCOMPtr bodyElement; - res = GetBodyElement(getter_AddRefs(bodyElement)); + res = GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; if (!bodyElement) return NS_ERROR_NULL_POINTER; @@ -5115,7 +5137,7 @@ nsHTMLEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivat nsCOMPtr ps = do_QueryReferent(mPresShellWeak); if (!ps) return NS_ERROR_NOT_INITIALIZED; ps->GetCaret(getter_AddRefs(caretP)); - caretP->GetWindowRelativeCoordinates(aReply->mCursorPosition,aReply->mCursorIsCollapsed); + caretP->GetWindowRelativeCoordinates(aReply->mCursorPosition,aReply->mCursorIsCollapsed,selection); // second part of 23558 fix: if (aCompositionString.IsEmpty()) @@ -5228,7 +5250,7 @@ nsHTMLEditor::SelectEntireDocument(nsIDOMSelection *aSelection) // get body node nsCOMPtrbodyElement; - res = GetBodyElement(getter_AddRefs(bodyElement)); + res = GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; nsCOMPtrbodyNode = do_QueryInterface(bodyElement); if (!bodyNode) return NS_ERROR_FAILURE; @@ -5383,29 +5405,7 @@ void nsHTMLEditor::IsTextStyleSet(nsIStyleContext *aSC, PRBool nsHTMLEditor::IsElementInBody(nsIDOMElement* aElement) { - if ( aElement ) - { - nsIDOMElement* bodyElement = nsnull; - nsresult res = nsEditor::GetBodyElement(&bodyElement); - if (NS_FAILED(res)) return res; - if (!bodyElement) return NS_ERROR_NULL_POINTER; - nsCOMPtr parent; - nsCOMPtr currentElement = do_QueryInterface(aElement); - if (currentElement) - { - do { - currentElement->GetParentNode(getter_AddRefs(parent)); - if (parent) - { - if (parent == bodyElement) - return PR_TRUE; - - currentElement = parent; - } - } while(parent); - } - } - return PR_FALSE; + return nsHTMLEditUtils::InBody(aElement, this); } PRBool @@ -5929,7 +5929,7 @@ NS_IMETHODIMP nsHTMLEditor::SetSelectionAtDocumentStart(nsIDOMSelection *aSelection) { nsCOMPtr bodyElement; - nsresult res = GetBodyElement(getter_AddRefs(bodyElement)); + nsresult res = GetRootElement(getter_AddRefs(bodyElement)); if (NS_SUCCEEDED(res)) { if (!bodyElement) return NS_ERROR_NULL_POINTER; @@ -6324,7 +6324,7 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr *outNode if (NS_FAILED(res)) return res; // if it's not in the body, then zero it out - if (*outNode && !nsHTMLEditUtils::InBody(*outNode)) + if (*outNode && !nsHTMLEditUtils::InBody(*outNode, this)) { *outNode = nsnull; } @@ -6343,7 +6343,7 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr< if (NS_FAILED(res)) return res; // if it's not in the body, then zero it out - if (*outNode && !nsHTMLEditUtils::InBody(*outNode)) + if (*outNode && !nsHTMLEditUtils::InBody(*outNode, this)) { *outNode = nsnull; } @@ -6363,7 +6363,7 @@ nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr *outNode) if (NS_FAILED(res)) return res; // if it's not in the body, then zero it out - if (*outNode && !nsHTMLEditUtils::InBody(*outNode)) + if (*outNode && !nsHTMLEditUtils::InBody(*outNode, this)) { *outNode = nsnull; } @@ -6382,7 +6382,7 @@ nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr bodyElement; - res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); + res = mEditor->GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; if (!bodyElement) return NS_ERROR_NULL_POINTER; nsCOMPtrbodyNode = do_QueryInterface(bodyElement); @@ -120,7 +120,15 @@ nsTextEditRules::Init(nsHTMLEditor *aEditor, PRUint32 aFlags) res = nsComponentManager::CreateInstance(kRangeCID, nsnull, NS_GET_IID(nsIDOMRange), getter_AddRefs(wholeDoc)); if (NS_FAILED(res)) return res; - res = wholeDoc->SelectNode(bodyNode); + wholeDoc->SetStart(bodyNode,0); + nsCOMPtr list; + res = bodyNode->GetChildNodes(getter_AddRefs(list)); + if (NS_FAILED(res) || !list) return res?res:NS_ERROR_FAILURE; + PRUint32 listCount; + res = list->GetLength(&listCount); + if (NS_FAILED(res)) return res; + + res = wholeDoc->SetEnd(bodyNode,listCount); if (NS_FAILED(res)) return res; // replace newlines in that range with breaks @@ -967,7 +975,7 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult) else { nsCOMPtr theBody; - res = mEditor->GetBodyElement(getter_AddRefs(theBody)); + res = mEditor->GetRootElement(getter_AddRefs(theBody)); if (NS_FAILED(res)) return res; if (!theBody) return NS_ERROR_FAILURE; @@ -1016,7 +1024,7 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult) else { nsCOMPtr theBody; - res = mEditor->GetBodyElement(getter_AddRefs(theBody)); + res = mEditor->GetRootElement(getter_AddRefs(theBody)); if (NS_FAILED(res)) return res; if (!theBody) return NS_ERROR_FAILURE; @@ -1186,7 +1194,7 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection) nsCOMPtr bodyElement; - nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); + nsresult res = mEditor->GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; if (!bodyElement) return NS_ERROR_NULL_POINTER; nsCOMPtrbodyNode = do_QueryInterface(bodyElement); diff --git a/editor/composer/src/nsEditorShell.cpp b/editor/composer/src/nsEditorShell.cpp index e7ac4124105d..40631fdfc1e7 100644 --- a/editor/composer/src/nsEditorShell.cpp +++ b/editor/composer/src/nsEditorShell.cpp @@ -662,17 +662,17 @@ nsEditorShell::InstantiateEditor(nsIDOMDocument *aDoc, nsIPresShell *aPresShell) { if (mEditorTypeString.EqualsWithConversion("text")) { - err = editor->Init(aDoc, aPresShell, selCon, nsIHTMLEditor::eEditorPlaintextMask); + err = editor->Init(aDoc, aPresShell, nsnull, selCon, nsIHTMLEditor::eEditorPlaintextMask); mEditorType = ePlainTextEditorType; } else if (mEditorTypeString.EqualsWithConversion("html") || mEditorTypeString.IsEmpty()) // empty string default to HTML editor { - err = editor->Init(aDoc, aPresShell, selCon, 0); + err = editor->Init(aDoc, aPresShell, nsnull, selCon, 0); mEditorType = eHTMLTextEditorType; } else if (mEditorTypeString.EqualsWithConversion("htmlmail")) // HTML editor with special mail rules { - err = editor->Init(aDoc, aPresShell, selCon, nsIHTMLEditor::eEditorMailMask); + err = editor->Init(aDoc, aPresShell, nsnull, selCon, nsIHTMLEditor::eEditorMailMask); mEditorType = eHTMLTextEditorType; } else diff --git a/editor/libeditor/base/nsEditor.cpp b/editor/libeditor/base/nsEditor.cpp index 3579aef41afe..fa498408d775 100644 --- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -827,7 +827,7 @@ NS_IMPL_QUERY_INTERFACE3(nsEditor, nsIEditor, nsIEditorIMESupport, nsISupportsWe NS_IMETHODIMP -nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsISelectionController *aSelCon, PRUint32 aFlags) +nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags) { NS_PRECONDITION(nsnull!=aDoc && nsnull!=aPresShell, "bad arg"); if ((nsnull==aDoc) || (nsnull==aPresShell)) @@ -840,6 +840,10 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsISelectionContr nsCOMPtr ps = do_QueryReferent(mPresShellWeak); if (!ps) return NS_ERROR_NOT_INITIALIZED; + //set up body element if we are passed one. + if (aRoot) + mBodyElement = do_QueryInterface(aRoot); + // disable links nsCOMPtr context; ps->GetPresContext(getter_AddRefs(context)); @@ -2342,7 +2346,7 @@ nsEditor::ForceCompositionEnd() // 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::GetBodyElement(nsIDOMElement **aBodyElement) +nsEditor::GetRootElement(nsIDOMElement **aBodyElement) { nsresult result = NS_OK; @@ -2645,7 +2649,7 @@ NS_IMETHODIMP nsEditor::SelectEntireDocument(nsIDOMSelection *aSelection) nsresult result; if (!aSelection) { return NS_ERROR_NULL_POINTER; } nsCOMPtrbodyElement; - result = GetBodyElement(getter_AddRefs(bodyElement)); + result = GetRootElement(getter_AddRefs(bodyElement)); if ((NS_SUCCEEDED(result)) && bodyElement) { nsCOMPtrbodyNode = do_QueryInterface(bodyElement); diff --git a/editor/libeditor/base/nsEditor.h b/editor/libeditor/base/nsEditor.h index ddf12e66c7f9..a0e87535a775 100644 --- a/editor/libeditor/base/nsEditor.h +++ b/editor/libeditor/base/nsEditor.h @@ -189,11 +189,12 @@ public: NS_DECL_ISUPPORTS /* ------------ nsIEditor methods -------------- */ - NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell, nsISelectionController *aSelCon, PRUint32 aFlags); + NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell, nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags); NS_IMETHOD PostCreate(); NS_IMETHOD GetFlags(PRUint32 *aFlags) = 0; NS_IMETHOD SetFlags(PRUint32 aFlags) = 0; NS_IMETHOD GetDocument(nsIDOMDocument **aDoc); + NS_IMETHOD GetRootElement(nsIDOMElement **aElement); NS_IMETHOD GetPresShell(nsIPresShell **aPS); NS_IMETHOD GetSelectionController(nsISelectionController **aSel); NS_IMETHOD GetSelection(nsIDOMSelection **aSelection); @@ -460,10 +461,6 @@ protected: public: - /** return the body element */ - /** It would make more sense for this to be in nsHTMLEditor, no? */ - NS_IMETHOD GetBodyElement(nsIDOMElement **aElement); - /** All editor operations which alter the doc should be prefaced * with a call to StartOperation, naming the action and direction */ NS_IMETHOD StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection); diff --git a/editor/libeditor/html/nsHTMLEditRules.cpp b/editor/libeditor/html/nsHTMLEditRules.cpp index 5e95fd27b430..6b1d768dac5f 100644 --- a/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/editor/libeditor/html/nsHTMLEditRules.cpp @@ -126,7 +126,7 @@ nsHTMLEditRules::Init(nsHTMLEditor *aEditor, PRUint32 aFlags) // set up mDocChangeRange to be whole doc nsCOMPtr bodyElem; nsCOMPtr bodyNode; - mEditor->GetBodyElement(getter_AddRefs(bodyElem)); + mEditor->GetRootElement(getter_AddRefs(bodyElem)); bodyNode = do_QueryInterface(bodyElem); if (bodyNode) { @@ -857,7 +857,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, if (NS_FAILED(res)) return res; // if there is no next node, or it's not in the body, then cancel the deletion - if (!nextNode || !nsHTMLEditUtils::InBody(nextNode)) + if (!nextNode || !nsHTMLEditUtils::InBody(nextNode, mEditor)) { *aCancel = PR_TRUE; return res; @@ -4461,7 +4461,7 @@ nsHTMLEditRules::ConfirmSelectionInBody() nsCOMPtr bodyNode; // get the body - res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); + res = mEditor->GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; if (!bodyElement) return NS_ERROR_UNEXPECTED; bodyNode = do_QueryInterface(bodyElement); diff --git a/editor/libeditor/html/nsHTMLEditRules.h b/editor/libeditor/html/nsHTMLEditRules.h index 6c038fd56547..478fbd7a1e5c 100644 --- a/editor/libeditor/html/nsHTMLEditRules.h +++ b/editor/libeditor/html/nsHTMLEditRules.h @@ -33,6 +33,7 @@ class nsISupportsArray; class nsVoidArray; class nsIDOMElement; +class nsIEditor; class nsHTMLEditRules : public nsIHTMLEditRules, nsTextEditRules, nsIEditActionListener { diff --git a/editor/libeditor/html/nsHTMLEditUtils.cpp b/editor/libeditor/html/nsHTMLEditUtils.cpp index 80fb72b93b7a..d57310c355bb 100644 --- a/editor/libeditor/html/nsHTMLEditUtils.cpp +++ b/editor/libeditor/html/nsHTMLEditUtils.cpp @@ -143,20 +143,25 @@ nsHTMLEditUtils::HasMozAttr(nsIDOMNode *node) // InBody: true if node is a descendant of the body // PRBool -nsHTMLEditUtils::InBody(nsIDOMNode *node) +nsHTMLEditUtils::InBody(nsIDOMNode *node, nsIEditor *editor) { - NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::InBody"); - nsCOMPtr tmp; - nsCOMPtr p = do_QueryInterface(node); - - while (p && !IsBody(p)) + if ( node ) { - if ( NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp) // no parent, ran off top of tree - return PR_FALSE; - p = tmp; + nsCOMPtr bodyElement; + nsresult res = editor->GetRootElement(getter_AddRefs(bodyElement)); + if (NS_FAILED(res) || !bodyElement) + return res?res:NS_ERROR_NULL_POINTER; + nsCOMPtr bodyNode = do_QueryInterface(bodyElement); + nsCOMPtr tmp; + nsCOMPtr p = node; + while (p && p!= bodyNode) + { + if (NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp) + return PR_FALSE; + p = tmp; + } } - if (p) return PR_TRUE; - return PR_FALSE; + return PR_TRUE; } diff --git a/editor/libeditor/html/nsHTMLEditUtils.h b/editor/libeditor/html/nsHTMLEditUtils.h index 16d3046584de..e956cbf16c63 100644 --- a/editor/libeditor/html/nsHTMLEditUtils.h +++ b/editor/libeditor/html/nsHTMLEditUtils.h @@ -25,7 +25,7 @@ #include "prtypes.h" // for PRBool #include "nsError.h" // for nsresult - +class nsIEditor; class nsIDOMNode; class nsHTMLEditUtils @@ -38,7 +38,7 @@ public: static PRBool IsSmall(nsIDOMNode *aNode); static PRBool IsMozBR(nsIDOMNode *aNode); static PRBool HasMozAttr(nsIDOMNode *aNode); - static PRBool InBody(nsIDOMNode *aNode); + static PRBool InBody(nsIDOMNode *aNode, nsIEditor *aEditor); // from nsHTMLEditRules: static PRBool IsHeader(nsIDOMNode *aNode); diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp index 3b4d0c819be8..aed62ff2f160 100644 --- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -380,7 +380,7 @@ NS_IMETHODIMP nsHTMLEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr) NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, - nsIPresShell *aPresShell, nsISelectionController *aSelCon, PRUint32 aFlags) + nsIPresShell *aPresShell, nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags) { NS_PRECONDITION(aDoc && aPresShell, "bad arg"); if (!aDoc || !aPresShell) @@ -388,11 +388,11 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, nsresult result = NS_ERROR_NULL_POINTER; // Init the base editor - result = nsEditor::Init(aDoc, aPresShell, aSelCon, aFlags); + result = nsEditor::Init(aDoc, aPresShell, aRoot, aSelCon, aFlags); if (NS_FAILED(result)) { return result; } nsCOMPtr bodyElement; - result = nsEditor::GetBodyElement(getter_AddRefs(bodyElement)); + result = nsEditor::GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(result)) { return result; } if (!bodyElement) { return NS_ERROR_NULL_POINTER; } @@ -585,10 +585,32 @@ printf("nsTextEditor.cpp: failed to get TextEvent Listener\n"); } // get the DOM event receiver + nsCOMPtr domdoc; + nsEditor::GetDocument(getter_AddRefs(domdoc)); nsCOMPtr erP; - nsCOMPtr doc = do_QueryReferent(mDocWeak); - if (!doc) return NS_ERROR_NOT_INITIALIZED; - result = doc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + nsCOMPtr rootElement; + GetRootElement(getter_AddRefs(rootElement)); + //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; + if (NS_SUCCEEDED(content->GetParent(*getter_AddRefs(parent))) && parent) + { + PRInt32 index; + if (NS_FAILED(parent->IndexOf(content, index)) || index<0 ) + { + rootElement = do_QueryInterface(parent); + result = rootElement->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + } + else + rootElement = 0; + } + } + if (!rootElement && domdoc) + result = domdoc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + //end hack if (NS_FAILED(result)) { HandleEventListenerError(); return result; @@ -3625,7 +3647,7 @@ nsHTMLEditor::SetBackgroundColor(const nsString& 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::GetBodyElement(getter_AddRefs(element)); + res = nsEditor::GetRootElement(getter_AddRefs(element)); if (NS_FAILED(res)) return res; if (!element) return NS_ERROR_NULL_POINTER; } @@ -3643,7 +3665,7 @@ NS_IMETHODIMP nsHTMLEditor::SetBodyAttribute(const nsString& aAttribute, const n // Set the background color attribute on the body tag nsCOMPtr bodyElement; - res = nsEditor::GetBodyElement(getter_AddRefs(bodyElement)); + res = nsEditor::GetRootElement(getter_AddRefs(bodyElement)); if (!bodyElement) res = NS_ERROR_NULL_POINTER; if (NS_SUCCEEDED(res)) { @@ -3734,7 +3756,7 @@ nsHTMLEditor::GetDocumentLength(PRInt32 *aCount) // get the body node nsCOMPtr bodyElement; - result = nsEditor::GetBodyElement(getter_AddRefs(bodyElement)); + result = nsEditor::GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(result)) { return result; } if (!bodyElement) { return NS_ERROR_NULL_POINTER; } @@ -3957,7 +3979,7 @@ NS_IMETHODIMP nsHTMLEditor::GetBodyStyleContext(nsIStyleContext** aStyleContext) { nsCOMPtr body; - nsresult res = GetBodyElement(getter_AddRefs(body)); + nsresult res = GetRootElement(getter_AddRefs(body)); if (NS_FAILED(res)) return res; nsCOMPtr content = do_QueryInterface(body); @@ -4044,7 +4066,7 @@ NS_IMETHODIMP nsHTMLEditor::SetBodyWrapWidth(PRInt32 aWrapColumn) // Ought to set a style sheet here ... // Probably should keep around an mPlaintextStyleSheet for this purpose. nsCOMPtr bodyElement; - res = GetBodyElement(getter_AddRefs(bodyElement)); + res = GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; if (!bodyElement) return NS_ERROR_NULL_POINTER; @@ -5115,7 +5137,7 @@ nsHTMLEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivat nsCOMPtr ps = do_QueryReferent(mPresShellWeak); if (!ps) return NS_ERROR_NOT_INITIALIZED; ps->GetCaret(getter_AddRefs(caretP)); - caretP->GetWindowRelativeCoordinates(aReply->mCursorPosition,aReply->mCursorIsCollapsed); + caretP->GetWindowRelativeCoordinates(aReply->mCursorPosition,aReply->mCursorIsCollapsed,selection); // second part of 23558 fix: if (aCompositionString.IsEmpty()) @@ -5228,7 +5250,7 @@ nsHTMLEditor::SelectEntireDocument(nsIDOMSelection *aSelection) // get body node nsCOMPtrbodyElement; - res = GetBodyElement(getter_AddRefs(bodyElement)); + res = GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; nsCOMPtrbodyNode = do_QueryInterface(bodyElement); if (!bodyNode) return NS_ERROR_FAILURE; @@ -5383,29 +5405,7 @@ void nsHTMLEditor::IsTextStyleSet(nsIStyleContext *aSC, PRBool nsHTMLEditor::IsElementInBody(nsIDOMElement* aElement) { - if ( aElement ) - { - nsIDOMElement* bodyElement = nsnull; - nsresult res = nsEditor::GetBodyElement(&bodyElement); - if (NS_FAILED(res)) return res; - if (!bodyElement) return NS_ERROR_NULL_POINTER; - nsCOMPtr parent; - nsCOMPtr currentElement = do_QueryInterface(aElement); - if (currentElement) - { - do { - currentElement->GetParentNode(getter_AddRefs(parent)); - if (parent) - { - if (parent == bodyElement) - return PR_TRUE; - - currentElement = parent; - } - } while(parent); - } - } - return PR_FALSE; + return nsHTMLEditUtils::InBody(aElement, this); } PRBool @@ -5929,7 +5929,7 @@ NS_IMETHODIMP nsHTMLEditor::SetSelectionAtDocumentStart(nsIDOMSelection *aSelection) { nsCOMPtr bodyElement; - nsresult res = GetBodyElement(getter_AddRefs(bodyElement)); + nsresult res = GetRootElement(getter_AddRefs(bodyElement)); if (NS_SUCCEEDED(res)) { if (!bodyElement) return NS_ERROR_NULL_POINTER; @@ -6324,7 +6324,7 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr *outNode if (NS_FAILED(res)) return res; // if it's not in the body, then zero it out - if (*outNode && !nsHTMLEditUtils::InBody(*outNode)) + if (*outNode && !nsHTMLEditUtils::InBody(*outNode, this)) { *outNode = nsnull; } @@ -6343,7 +6343,7 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr< if (NS_FAILED(res)) return res; // if it's not in the body, then zero it out - if (*outNode && !nsHTMLEditUtils::InBody(*outNode)) + if (*outNode && !nsHTMLEditUtils::InBody(*outNode, this)) { *outNode = nsnull; } @@ -6363,7 +6363,7 @@ nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr *outNode) if (NS_FAILED(res)) return res; // if it's not in the body, then zero it out - if (*outNode && !nsHTMLEditUtils::InBody(*outNode)) + if (*outNode && !nsHTMLEditUtils::InBody(*outNode, this)) { *outNode = nsnull; } @@ -6382,7 +6382,7 @@ nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr bodyElement; - res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); + res = mEditor->GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; if (!bodyElement) return NS_ERROR_NULL_POINTER; nsCOMPtrbodyNode = do_QueryInterface(bodyElement); @@ -120,7 +120,15 @@ nsTextEditRules::Init(nsHTMLEditor *aEditor, PRUint32 aFlags) res = nsComponentManager::CreateInstance(kRangeCID, nsnull, NS_GET_IID(nsIDOMRange), getter_AddRefs(wholeDoc)); if (NS_FAILED(res)) return res; - res = wholeDoc->SelectNode(bodyNode); + wholeDoc->SetStart(bodyNode,0); + nsCOMPtr list; + res = bodyNode->GetChildNodes(getter_AddRefs(list)); + if (NS_FAILED(res) || !list) return res?res:NS_ERROR_FAILURE; + PRUint32 listCount; + res = list->GetLength(&listCount); + if (NS_FAILED(res)) return res; + + res = wholeDoc->SetEnd(bodyNode,listCount); if (NS_FAILED(res)) return res; // replace newlines in that range with breaks @@ -967,7 +975,7 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult) else { nsCOMPtr theBody; - res = mEditor->GetBodyElement(getter_AddRefs(theBody)); + res = mEditor->GetRootElement(getter_AddRefs(theBody)); if (NS_FAILED(res)) return res; if (!theBody) return NS_ERROR_FAILURE; @@ -1016,7 +1024,7 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult) else { nsCOMPtr theBody; - res = mEditor->GetBodyElement(getter_AddRefs(theBody)); + res = mEditor->GetRootElement(getter_AddRefs(theBody)); if (NS_FAILED(res)) return res; if (!theBody) return NS_ERROR_FAILURE; @@ -1186,7 +1194,7 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection) nsCOMPtr bodyElement; - nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); + nsresult res = mEditor->GetRootElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; if (!bodyElement) return NS_ERROR_NULL_POINTER; nsCOMPtrbodyNode = do_QueryInterface(bodyElement); diff --git a/editor/public/nsIEditor.h b/editor/public/nsIEditor.h index baabc8692c73..f1601421eb4b 100644 --- a/editor/public/nsIEditor.h +++ b/editor/public/nsIEditor.h @@ -46,6 +46,8 @@ class nsIEditActionListener; class nsIDocumentStateListener; class nsFileSpec; class nsISelectionController; +class nsIContent; + class nsIEditor : public nsISupports { public: @@ -70,9 +72,11 @@ public: * once events can tell us from what pres shell they originated, * this will no longer be necessary and the editor will no longer be * linked to a single pres shell. + * @param aRoot This is the root of the editable section of this document. if it is null then we get root from document body. + * @param aSelCon this should be used to get the selection location * @param aFlags A bitmask of flags for specifying the behavior of the editor. */ - NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell, nsISelectionController *aSelCon, PRUint32 aFlags)=0; + NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell, nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags)=0; /** * PostCreate should be called after Init, and is the time that the editor tells @@ -93,6 +97,11 @@ public: */ NS_IMETHOD GetDocument(nsIDOMDocument **aDoc)=0; + /** return the body element + * @param aElement return value for the root of the editable document + */ + NS_IMETHOD GetRootElement(nsIDOMElement **aElement)=0; + /** * return the presentation shell this editor is associated with * @@ -115,6 +124,7 @@ public: */ NS_IMETHOD GetSelection(nsIDOMSelection **aSelection)=0; + /* ------------ Selected content removal -------------- */ /**