From af793dca0e19664cf38fcc59cf37c9065cec0868 Mon Sep 17 00:00:00 2001 From: "jfrancis%netscape.com" Date: Fri, 2 Jun 2000 07:47:53 +0000 Subject: [PATCH] backend work for 41034: getting format feedback and list feedback untangled from each other. git-svn-id: svn://10.0.0.236/trunk@71349 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/editor/base/nsComposerCommands.cpp | 18 +- mozilla/editor/base/nsHTMLEditRules.cpp | 218 +++++++++--------- mozilla/editor/base/nsHTMLEditRules.h | 7 +- mozilla/editor/base/nsHTMLEditor.cpp | 15 +- mozilla/editor/base/nsHTMLEditor.h | 3 +- mozilla/editor/base/nsIHTMLEditRules.h | 3 +- mozilla/editor/base/nsInterfaceState.cpp | 6 +- .../composer/src/nsComposerCommands.cpp | 18 +- .../editor/composer/src/nsInterfaceState.cpp | 6 +- .../editor/libeditor/html/nsHTMLEditRules.cpp | 218 +++++++++--------- .../editor/libeditor/html/nsHTMLEditRules.h | 7 +- .../editor/libeditor/html/nsHTMLEditor.cpp | 15 +- mozilla/editor/libeditor/html/nsHTMLEditor.h | 3 +- .../editor/libeditor/html/nsIHTMLEditRules.h | 3 +- mozilla/editor/public/nsIHTMLEditor.h | 13 +- 15 files changed, 316 insertions(+), 237 deletions(-) diff --git a/mozilla/editor/base/nsComposerCommands.cpp b/mozilla/editor/base/nsComposerCommands.cpp index 85c0212ffa4..c5bdde8256c 100644 --- a/mozilla/editor/base/nsComposerCommands.cpp +++ b/mozilla/editor/base/nsComposerCommands.cpp @@ -411,14 +411,15 @@ nsListCommand::GetCurrentState(nsIEditorShell *aEditorShell, const char* aTagNam // tagStr will hold the list state when we're done. nsAutoString tagStr; - PRBool bMixed, bOL, bUL; - nsresult rv = htmlEditor->GetListState(bMixed, bOL, bUL); + PRBool bMixed, bOL, bUL, bDL; + nsresult rv = htmlEditor->GetListState(bMixed, bOL, bUL, bDL); if (NS_FAILED(rv)) return rv; if (!bMixed) { if (bOL) tagStr.AssignWithConversion("ol"); else if (bUL) tagStr.AssignWithConversion("ul"); + else if (bDL) tagStr.AssignWithConversion("dl"); } outInList = tagStr.EqualsWithConversion(mTagName); @@ -622,7 +623,18 @@ nsParagraphStateCommand::GetCurrentState(nsIEditorShell *aEditorShell, nsString& aEditorShell->GetEditor(getter_AddRefs(editor)); nsCOMPtr htmlEditor = do_QueryInterface(editor); if (!htmlEditor) return NS_ERROR_FAILURE; - +#if 0 + // some proof of concept code for list item state. + // Just leaving in for Charlie to see. + PRBool bLI,bDT,bDD; + htmlEditor->GetListItemState(outMixed, bLI, bDT, bDD); + if (!outMixed && (bDT || bDD)) + { + if (bDT) outStateString.AssignWithConversion("DT"); + if (bDD) outStateString.AssignWithConversion("DD"); + return NS_OK; + } +#endif return htmlEditor->GetParagraphState(outMixed, outStateString); } diff --git a/mozilla/editor/base/nsHTMLEditRules.cpp b/mozilla/editor/base/nsHTMLEditRules.cpp index cf503e5f5ae..f25a9d34daa 100644 --- a/mozilla/editor/base/nsHTMLEditRules.cpp +++ b/mozilla/editor/base/nsHTMLEditRules.cpp @@ -350,11 +350,12 @@ nsHTMLEditRules::DidDoAction(nsIDOMSelection *aSelection, ********************************************************/ NS_IMETHODIMP -nsHTMLEditRules::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL) +nsHTMLEditRules::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL) { aMixed = PR_FALSE; aOL = PR_FALSE; aUL = PR_FALSE; + aDL = PR_FALSE; PRBool bNonList = PR_FALSE; nsCOMPtr arrayOfNodes; @@ -370,11 +371,11 @@ nsHTMLEditRules::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL) nsCOMPtr isupports = (dont_AddRef)(arrayOfNodes->ElementAt(i)); nsCOMPtr curNode( do_QueryInterface(isupports) ); - if (nsHTMLEditUtils::IsUnorderedList(curNode)) + if (mEditor->NodeIsType(curNode,nsIEditProperty::ul)) aUL = PR_TRUE; - else if (nsHTMLEditUtils::IsOrderedList(curNode)) + else if (mEditor->NodeIsType(curNode,nsIEditProperty::ol)) aOL = PR_TRUE; - else if (nsHTMLEditUtils::IsListItem(curNode)) + else if (mEditor->NodeIsType(curNode,nsIEditProperty::li)) { nsCOMPtr parent; PRInt32 offset; @@ -385,11 +386,71 @@ nsHTMLEditRules::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL) else if (nsHTMLEditUtils::IsOrderedList(parent)) aOL = PR_TRUE; } + else if (mEditor->NodeIsType(curNode,nsIEditProperty::dl) || + mEditor->NodeIsType(curNode,nsIEditProperty::dt) || + mEditor->NodeIsType(curNode,nsIEditProperty::dd) ) + { + aDL = PR_TRUE; + } else bNonList = PR_TRUE; } // hokey arithmetic with booleans - if ( (aUL + aOL + bNonList) > 1) aMixed = PR_TRUE; + if ( (aUL + aOL + aDL + bNonList) > 1) aMixed = PR_TRUE; + + return res; +} + +NS_IMETHODIMP +nsHTMLEditRules::GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD) +{ + aMixed = PR_FALSE; + aLI = PR_FALSE; + aDT = PR_FALSE; + aDD = PR_FALSE; + PRBool bNonList = PR_FALSE; + + nsCOMPtr arrayOfNodes; + nsresult res = GetListActionNodes(&arrayOfNodes, PR_TRUE); + if (NS_FAILED(res)) return res; + + // examine list type for nodes in selection + PRUint32 listCount; + PRInt32 i; + arrayOfNodes->Count(&listCount); + for (i=(PRInt32)listCount-1; i>=0; i--) + { + nsCOMPtr isupports = (dont_AddRef)(arrayOfNodes->ElementAt(i)); + nsCOMPtr curNode( do_QueryInterface(isupports) ); + + if (mEditor->NodeIsType(curNode,nsIEditProperty::ul) || + mEditor->NodeIsType(curNode,nsIEditProperty::ol) || + mEditor->NodeIsType(curNode,nsIEditProperty::li) ) + { + aLI = PR_TRUE; + } + else if (mEditor->NodeIsType(curNode,nsIEditProperty::dt)) + { + aDT = PR_TRUE; + } + else if (mEditor->NodeIsType(curNode,nsIEditProperty::dd)) + { + aDD = PR_TRUE; + } + else if (mEditor->NodeIsType(curNode,nsIEditProperty::dl)) + { + // need to look inside dl and see which types of items it has + PRBool bDT, bDD; + res = GetDefinitionListItemTypes(curNode, bDT, bDD); + if (NS_FAILED(res)) return res; + aDT |= bDT; + aDD |= bDD; + } + else bNonList = PR_TRUE; + } + + // hokey arithmetic with booleans + if ( (aDT + aDD + bNonList) > 1) aMixed = PR_TRUE; return res; } @@ -2362,107 +2423,41 @@ nsHTMLEditRules::AlignTableCellContents(nsIDOMNode *aNode, const nsString *align } + /////////////////////////////////////////////////////////////////////////// -// GetTableContent: take a table element and list it's editable, non-table contents +// GetInnerContent: aList and aTbl allow the caller to specify what kind +// of content to "look inside". If aTbl is true, look inside +// any table content, and append the inner content to the +// supplied issupportsarray. Similarly with aList and list content. // nsresult -nsHTMLEditRules::GetTableContent(nsIDOMNode *aNode, nsCOMPtr *outArrayOfNodes) +nsHTMLEditRules::GetInnerContent(nsIDOMNode *aNode, nsISupportsArray *outArrayOfNodes, PRBool aList, PRBool aTbl) { if (!aNode || !outArrayOfNodes) return NS_ERROR_NULL_POINTER; - // make a array - nsresult res = NS_NewISupportsArray(getter_AddRefs(*outArrayOfNodes)); - if (NS_FAILED(res)) return res; - - // make an iter - nsCOMPtr iter; - res = nsComponentManager::CreateInstance(kContentIteratorCID, nsnull, - NS_GET_IID(nsIContentIterator), - getter_AddRefs(iter)); - if (NS_FAILED(res)) return res; - if (!iter) return NS_ERROR_FAILURE; - - nsCOMPtr content; nsCOMPtr node; nsCOMPtr isupports; - // iterate node and build up array of non-table content - content = do_QueryInterface(aNode); - iter->Init(content); - while (NS_ENUMERATOR_FALSE == iter->IsDone()) + nsresult res = mEditor->GetFirstEditableChild(aNode, &node); + while (NS_SUCCEEDED(res) && node) { - res = iter->CurrentNode(getter_AddRefs(content)); - if (NS_FAILED(res)) return res; - node = do_QueryInterface(content); - if (!node) return NS_ERROR_FAILURE; - if (mEditor->IsTableCell(node)) + if ( ( aList && (nsHTMLEditUtils::IsList(node) || + nsHTMLEditUtils::IsListItem(node) ) ) + || ( aTbl && mEditor->IsTableElement(node) ) ) { - nsCOMPtr child, tmp; - res = mEditor->GetFirstEditableChild(node, &child); + res = GetInnerContent(node, outArrayOfNodes, aList, aTbl); if (NS_FAILED(res)) return res; - while (child) - { - isupports = do_QueryInterface(child); - (*outArrayOfNodes)->AppendElement(isupports); - mEditor->GetNextHTMLSibling(child, &tmp); - child = tmp; - } } - res = iter->Next(); - if (NS_FAILED(res)) return res; - } - return res; -} - -/////////////////////////////////////////////////////////////////////////// -// GetListContent: take a list element and get it's editable, non-list contents -// -nsresult -nsHTMLEditRules::GetListContent(nsIDOMNode *aNode, nsCOMPtr *outArrayOfNodes) -{ - if (!aNode || !outArrayOfNodes) return NS_ERROR_NULL_POINTER; - - // make a array - nsresult res = NS_NewISupportsArray(getter_AddRefs(*outArrayOfNodes)); - if (NS_FAILED(res)) return res; - - // make an iter - nsCOMPtr iter; - res = nsComponentManager::CreateInstance(kContentIteratorCID, nsnull, - NS_GET_IID(nsIContentIterator), - getter_AddRefs(iter)); - if (NS_FAILED(res)) return res; - if (!iter) return NS_ERROR_FAILURE; - - nsCOMPtr content; - nsCOMPtr node; - nsCOMPtr isupports; - - // iterate node and build up array of non-list content - content = do_QueryInterface(aNode); - iter->Init(content); - while (NS_ENUMERATOR_FALSE == iter->IsDone()) - { - res = iter->CurrentNode(getter_AddRefs(content)); - if (NS_FAILED(res)) return res; - node = do_QueryInterface(content); - if (!node) return NS_ERROR_FAILURE; - if (nsHTMLEditUtils::IsList(node) || nsHTMLEditUtils::IsListItem(node)) + else { - nsCOMPtr child, tmp; - res = mEditor->GetFirstEditableChild(node, &child); - if (NS_FAILED(res)) return res; - while (child) - { - isupports = do_QueryInterface(child); - (*outArrayOfNodes)->AppendElement(isupports); - mEditor->GetNextHTMLSibling(child, &tmp); - child = tmp; - } + isupports = do_QueryInterface(node); + outArrayOfNodes->AppendElement(isupports); } - res = iter->Next(); - if (NS_FAILED(res)) return res; + nsCOMPtr tmp; + res = node->GetNextSibling(getter_AddRefs(tmp)); + node = tmp; } + return res; } @@ -3033,16 +3028,35 @@ nsHTMLEditRules::GetListActionNodes(nsCOMPtr *outArrayOfNodes, if (mEditor->IsTableElement(testNode) && !mEditor->IsTable(testNode)) { (*outArrayOfNodes)->RemoveElementAt(i); - nsCOMPtr arrayOfTableContent; - res = GetTableContent(testNode, &arrayOfTableContent); + res = GetInnerContent(testNode, *outArrayOfNodes, PR_FALSE); if (NS_FAILED(res)) return res; - (*outArrayOfNodes)->AppendElements(arrayOfTableContent); } } return res; } +/////////////////////////////////////////////////////////////////////////// +// GetDefinitionListItemTypes: +// +nsresult +nsHTMLEditRules::GetDefinitionListItemTypes(nsIDOMNode *aNode, PRBool &aDT, PRBool &aDD) +{ + if (!aNode) return NS_ERROR_NULL_POINTER; + aDT = aDD = PR_FALSE; + nsresult res = NS_OK; + nsCOMPtr child, temp; + res = aNode->GetFirstChild(getter_AddRefs(child)); + while (child && NS_SUCCEEDED(res)) + { + if (mEditor->NodeIsType(child,nsIEditProperty::dt)) aDT = PR_TRUE; + else if (mEditor->NodeIsType(child,nsIEditProperty::dd)) aDD = PR_TRUE; + res = child->GetNextSibling(getter_AddRefs(temp)); + child = temp; + } + return res; +} + /////////////////////////////////////////////////////////////////////////// // GetParagraphFormatNodes: // @@ -3080,22 +3094,14 @@ nsHTMLEditRules::GetParagraphFormatNodes(nsCOMPtr *outArrayOfN } // scan for table elements. If we find table elements other than table, - // replace it with a list of any editable non-table content. - if (mEditor->IsTableElement(testNode) && !mEditor->IsTable(testNode)) + // replace it with a list of any editable non-table content. Ditto for list elements. + if (mEditor->IsTableElement(testNode) || + nsHTMLEditUtils::IsList(testNode) || + nsHTMLEditUtils::IsListItem(testNode) ) { (*outArrayOfNodes)->RemoveElementAt(i); - nsCOMPtr arrayOfTableContent; - res = GetTableContent(testNode, &arrayOfTableContent); + res = GetInnerContent(testNode, *outArrayOfNodes); if (NS_FAILED(res)) return res; - (*outArrayOfNodes)->AppendElements(arrayOfTableContent); - } - else if (nsHTMLEditUtils::IsList(testNode) || nsHTMLEditUtils::IsListItem(testNode)) - { - (*outArrayOfNodes)->RemoveElementAt(i); - nsCOMPtr arrayOfTableContent; - res = GetListContent(testNode, &arrayOfTableContent); - if (NS_FAILED(res)) return res; - (*outArrayOfNodes)->AppendElements(arrayOfTableContent); } } return res; diff --git a/mozilla/editor/base/nsHTMLEditRules.h b/mozilla/editor/base/nsHTMLEditRules.h index c70838963fe..dbb5ecf9521 100644 --- a/mozilla/editor/base/nsHTMLEditRules.h +++ b/mozilla/editor/base/nsHTMLEditRules.h @@ -53,7 +53,8 @@ public: NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); // nsIHTMLEditRules methods - NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL); + NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL); + NS_IMETHOD GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD); NS_IMETHOD GetIndentState(PRBool &aCanIndent, PRBool &aCanOutdent); NS_IMETHOD GetParagraphState(PRBool &aMixed, nsString &outFormat); @@ -109,8 +110,7 @@ protected: nsresult AlignTableElement(nsIDOMNode *aNode, const nsString *alignType); nsresult AlignTableCellContents(nsIDOMNode *aNode, const nsString *alignType); - nsresult GetTableContent(nsIDOMNode *aNode, nsCOMPtr *outArrayOfNodes); - nsresult GetListContent(nsIDOMNode *aNode, nsCOMPtr *outArrayOfNodes); + nsresult GetInnerContent(nsIDOMNode *aNode, nsISupportsArray *outArrayOfNodes, PRBool aList = PR_TRUE, PRBool aTble = PR_TRUE); nsresult InsertTab(nsIDOMSelection *aSelection, nsString *outString); @@ -143,6 +143,7 @@ protected: nsresult GetChildNodesForOperation(nsIDOMNode *inNode, nsCOMPtr *outArrayOfNodes); nsresult GetListActionNodes(nsCOMPtr *outArrayOfNodes, PRBool aDontTouchContent=PR_FALSE); + nsresult GetDefinitionListItemTypes(nsIDOMNode *aNode, PRBool &aDT, PRBool &aDD); nsresult GetParagraphFormatNodes(nsCOMPtr *outArrayOfNodes, PRBool aDontTouchContent=PR_FALSE); nsresult BustUpInlinesAtBRs(nsIDOMNode *inNode, nsCOMPtr *outArrayOfNodes); diff --git a/mozilla/editor/base/nsHTMLEditor.cpp b/mozilla/editor/base/nsHTMLEditor.cpp index 5bd589ae42a..ba56888cf4f 100644 --- a/mozilla/editor/base/nsHTMLEditor.cpp +++ b/mozilla/editor/base/nsHTMLEditor.cpp @@ -3014,14 +3014,25 @@ nsHTMLEditor::GetFontFaceState(PRBool &aMixed, nsString &outFace) } NS_IMETHODIMP -nsHTMLEditor::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL) +nsHTMLEditor::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL) { if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } nsCOMPtr htmlRules = do_QueryInterface(mRules); if (!htmlRules) return NS_ERROR_FAILURE; - return htmlRules->GetListState(aMixed, aOL, aUL); + return htmlRules->GetListState(aMixed, aOL, aUL, aDL); +} + +NS_IMETHODIMP +nsHTMLEditor::GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD) +{ + if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } + + nsCOMPtr htmlRules = do_QueryInterface(mRules); + if (!htmlRules) return NS_ERROR_FAILURE; + + return htmlRules->GetListItemState(aMixed, aLI, aDT, aDD); } NS_IMETHODIMP diff --git a/mozilla/editor/base/nsHTMLEditor.h b/mozilla/editor/base/nsHTMLEditor.h index 48d3045f7a5..f9f30cce0b1 100644 --- a/mozilla/editor/base/nsHTMLEditor.h +++ b/mozilla/editor/base/nsHTMLEditor.h @@ -135,7 +135,8 @@ public: NS_IMETHOD GetParagraphState(PRBool &aMixed, nsString &outFormat); NS_IMETHOD GetFontFaceState(PRBool &aMixed, nsString &outFace); - NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL); + NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL); + NS_IMETHOD GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD); NS_IMETHOD GetIndentState(PRBool &aCanIndent, PRBool &aCanOutdent); NS_IMETHOD MakeOrChangeList(const nsString& aListType); diff --git a/mozilla/editor/base/nsIHTMLEditRules.h b/mozilla/editor/base/nsIHTMLEditRules.h index 141444c2ad2..092a8dfe127 100644 --- a/mozilla/editor/base/nsIHTMLEditRules.h +++ b/mozilla/editor/base/nsIHTMLEditRules.h @@ -33,7 +33,8 @@ class nsIHTMLEditRules : public nsISupports public: static const nsIID& GetIID() { static nsIID iid = NS_IHTMLEDITRULES_IID; return iid; } - NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL)=0; + NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL)=0; + NS_IMETHOD GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD)=0; NS_IMETHOD GetIndentState(PRBool &aCanIndent, PRBool &aCanOutdent)=0; NS_IMETHOD GetParagraphState(PRBool &aMixed, nsString &outFormat)=0; }; diff --git a/mozilla/editor/base/nsInterfaceState.cpp b/mozilla/editor/base/nsInterfaceState.cpp index 1b9633496b6..e62e0e88d75 100644 --- a/mozilla/editor/base/nsInterfaceState.cpp +++ b/mozilla/editor/base/nsInterfaceState.cpp @@ -493,8 +493,8 @@ nsInterfaceState::UpdateListState(const char* observerName) nsresult rv = NS_ERROR_NO_INTERFACE; nsAutoString tagStr; // empty by default. - PRBool bMixed, bOL, bUL; - rv = mEditor->GetListState(bMixed, bOL, bUL); + PRBool bMixed, bOL, bUL, bDL; + rv = mEditor->GetListState(bMixed, bOL, bUL, bDL); if (NS_FAILED(rv)) return rv; if (bMixed) @@ -503,6 +503,8 @@ nsInterfaceState::UpdateListState(const char* observerName) tagStr.AssignWithConversion("ol"); else if (bUL) tagStr.AssignWithConversion("ul"); + else if (bDL) + tagStr.AssignWithConversion("dl"); // else leave tagStr empty rv = SetNodeAttribute(observerName, "format", tagStr); diff --git a/mozilla/editor/composer/src/nsComposerCommands.cpp b/mozilla/editor/composer/src/nsComposerCommands.cpp index 85c0212ffa4..c5bdde8256c 100644 --- a/mozilla/editor/composer/src/nsComposerCommands.cpp +++ b/mozilla/editor/composer/src/nsComposerCommands.cpp @@ -411,14 +411,15 @@ nsListCommand::GetCurrentState(nsIEditorShell *aEditorShell, const char* aTagNam // tagStr will hold the list state when we're done. nsAutoString tagStr; - PRBool bMixed, bOL, bUL; - nsresult rv = htmlEditor->GetListState(bMixed, bOL, bUL); + PRBool bMixed, bOL, bUL, bDL; + nsresult rv = htmlEditor->GetListState(bMixed, bOL, bUL, bDL); if (NS_FAILED(rv)) return rv; if (!bMixed) { if (bOL) tagStr.AssignWithConversion("ol"); else if (bUL) tagStr.AssignWithConversion("ul"); + else if (bDL) tagStr.AssignWithConversion("dl"); } outInList = tagStr.EqualsWithConversion(mTagName); @@ -622,7 +623,18 @@ nsParagraphStateCommand::GetCurrentState(nsIEditorShell *aEditorShell, nsString& aEditorShell->GetEditor(getter_AddRefs(editor)); nsCOMPtr htmlEditor = do_QueryInterface(editor); if (!htmlEditor) return NS_ERROR_FAILURE; - +#if 0 + // some proof of concept code for list item state. + // Just leaving in for Charlie to see. + PRBool bLI,bDT,bDD; + htmlEditor->GetListItemState(outMixed, bLI, bDT, bDD); + if (!outMixed && (bDT || bDD)) + { + if (bDT) outStateString.AssignWithConversion("DT"); + if (bDD) outStateString.AssignWithConversion("DD"); + return NS_OK; + } +#endif return htmlEditor->GetParagraphState(outMixed, outStateString); } diff --git a/mozilla/editor/composer/src/nsInterfaceState.cpp b/mozilla/editor/composer/src/nsInterfaceState.cpp index 1b9633496b6..e62e0e88d75 100644 --- a/mozilla/editor/composer/src/nsInterfaceState.cpp +++ b/mozilla/editor/composer/src/nsInterfaceState.cpp @@ -493,8 +493,8 @@ nsInterfaceState::UpdateListState(const char* observerName) nsresult rv = NS_ERROR_NO_INTERFACE; nsAutoString tagStr; // empty by default. - PRBool bMixed, bOL, bUL; - rv = mEditor->GetListState(bMixed, bOL, bUL); + PRBool bMixed, bOL, bUL, bDL; + rv = mEditor->GetListState(bMixed, bOL, bUL, bDL); if (NS_FAILED(rv)) return rv; if (bMixed) @@ -503,6 +503,8 @@ nsInterfaceState::UpdateListState(const char* observerName) tagStr.AssignWithConversion("ol"); else if (bUL) tagStr.AssignWithConversion("ul"); + else if (bDL) + tagStr.AssignWithConversion("dl"); // else leave tagStr empty rv = SetNodeAttribute(observerName, "format", tagStr); diff --git a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp index cf503e5f5ae..f25a9d34daa 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp @@ -350,11 +350,12 @@ nsHTMLEditRules::DidDoAction(nsIDOMSelection *aSelection, ********************************************************/ NS_IMETHODIMP -nsHTMLEditRules::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL) +nsHTMLEditRules::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL) { aMixed = PR_FALSE; aOL = PR_FALSE; aUL = PR_FALSE; + aDL = PR_FALSE; PRBool bNonList = PR_FALSE; nsCOMPtr arrayOfNodes; @@ -370,11 +371,11 @@ nsHTMLEditRules::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL) nsCOMPtr isupports = (dont_AddRef)(arrayOfNodes->ElementAt(i)); nsCOMPtr curNode( do_QueryInterface(isupports) ); - if (nsHTMLEditUtils::IsUnorderedList(curNode)) + if (mEditor->NodeIsType(curNode,nsIEditProperty::ul)) aUL = PR_TRUE; - else if (nsHTMLEditUtils::IsOrderedList(curNode)) + else if (mEditor->NodeIsType(curNode,nsIEditProperty::ol)) aOL = PR_TRUE; - else if (nsHTMLEditUtils::IsListItem(curNode)) + else if (mEditor->NodeIsType(curNode,nsIEditProperty::li)) { nsCOMPtr parent; PRInt32 offset; @@ -385,11 +386,71 @@ nsHTMLEditRules::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL) else if (nsHTMLEditUtils::IsOrderedList(parent)) aOL = PR_TRUE; } + else if (mEditor->NodeIsType(curNode,nsIEditProperty::dl) || + mEditor->NodeIsType(curNode,nsIEditProperty::dt) || + mEditor->NodeIsType(curNode,nsIEditProperty::dd) ) + { + aDL = PR_TRUE; + } else bNonList = PR_TRUE; } // hokey arithmetic with booleans - if ( (aUL + aOL + bNonList) > 1) aMixed = PR_TRUE; + if ( (aUL + aOL + aDL + bNonList) > 1) aMixed = PR_TRUE; + + return res; +} + +NS_IMETHODIMP +nsHTMLEditRules::GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD) +{ + aMixed = PR_FALSE; + aLI = PR_FALSE; + aDT = PR_FALSE; + aDD = PR_FALSE; + PRBool bNonList = PR_FALSE; + + nsCOMPtr arrayOfNodes; + nsresult res = GetListActionNodes(&arrayOfNodes, PR_TRUE); + if (NS_FAILED(res)) return res; + + // examine list type for nodes in selection + PRUint32 listCount; + PRInt32 i; + arrayOfNodes->Count(&listCount); + for (i=(PRInt32)listCount-1; i>=0; i--) + { + nsCOMPtr isupports = (dont_AddRef)(arrayOfNodes->ElementAt(i)); + nsCOMPtr curNode( do_QueryInterface(isupports) ); + + if (mEditor->NodeIsType(curNode,nsIEditProperty::ul) || + mEditor->NodeIsType(curNode,nsIEditProperty::ol) || + mEditor->NodeIsType(curNode,nsIEditProperty::li) ) + { + aLI = PR_TRUE; + } + else if (mEditor->NodeIsType(curNode,nsIEditProperty::dt)) + { + aDT = PR_TRUE; + } + else if (mEditor->NodeIsType(curNode,nsIEditProperty::dd)) + { + aDD = PR_TRUE; + } + else if (mEditor->NodeIsType(curNode,nsIEditProperty::dl)) + { + // need to look inside dl and see which types of items it has + PRBool bDT, bDD; + res = GetDefinitionListItemTypes(curNode, bDT, bDD); + if (NS_FAILED(res)) return res; + aDT |= bDT; + aDD |= bDD; + } + else bNonList = PR_TRUE; + } + + // hokey arithmetic with booleans + if ( (aDT + aDD + bNonList) > 1) aMixed = PR_TRUE; return res; } @@ -2362,107 +2423,41 @@ nsHTMLEditRules::AlignTableCellContents(nsIDOMNode *aNode, const nsString *align } + /////////////////////////////////////////////////////////////////////////// -// GetTableContent: take a table element and list it's editable, non-table contents +// GetInnerContent: aList and aTbl allow the caller to specify what kind +// of content to "look inside". If aTbl is true, look inside +// any table content, and append the inner content to the +// supplied issupportsarray. Similarly with aList and list content. // nsresult -nsHTMLEditRules::GetTableContent(nsIDOMNode *aNode, nsCOMPtr *outArrayOfNodes) +nsHTMLEditRules::GetInnerContent(nsIDOMNode *aNode, nsISupportsArray *outArrayOfNodes, PRBool aList, PRBool aTbl) { if (!aNode || !outArrayOfNodes) return NS_ERROR_NULL_POINTER; - // make a array - nsresult res = NS_NewISupportsArray(getter_AddRefs(*outArrayOfNodes)); - if (NS_FAILED(res)) return res; - - // make an iter - nsCOMPtr iter; - res = nsComponentManager::CreateInstance(kContentIteratorCID, nsnull, - NS_GET_IID(nsIContentIterator), - getter_AddRefs(iter)); - if (NS_FAILED(res)) return res; - if (!iter) return NS_ERROR_FAILURE; - - nsCOMPtr content; nsCOMPtr node; nsCOMPtr isupports; - // iterate node and build up array of non-table content - content = do_QueryInterface(aNode); - iter->Init(content); - while (NS_ENUMERATOR_FALSE == iter->IsDone()) + nsresult res = mEditor->GetFirstEditableChild(aNode, &node); + while (NS_SUCCEEDED(res) && node) { - res = iter->CurrentNode(getter_AddRefs(content)); - if (NS_FAILED(res)) return res; - node = do_QueryInterface(content); - if (!node) return NS_ERROR_FAILURE; - if (mEditor->IsTableCell(node)) + if ( ( aList && (nsHTMLEditUtils::IsList(node) || + nsHTMLEditUtils::IsListItem(node) ) ) + || ( aTbl && mEditor->IsTableElement(node) ) ) { - nsCOMPtr child, tmp; - res = mEditor->GetFirstEditableChild(node, &child); + res = GetInnerContent(node, outArrayOfNodes, aList, aTbl); if (NS_FAILED(res)) return res; - while (child) - { - isupports = do_QueryInterface(child); - (*outArrayOfNodes)->AppendElement(isupports); - mEditor->GetNextHTMLSibling(child, &tmp); - child = tmp; - } } - res = iter->Next(); - if (NS_FAILED(res)) return res; - } - return res; -} - -/////////////////////////////////////////////////////////////////////////// -// GetListContent: take a list element and get it's editable, non-list contents -// -nsresult -nsHTMLEditRules::GetListContent(nsIDOMNode *aNode, nsCOMPtr *outArrayOfNodes) -{ - if (!aNode || !outArrayOfNodes) return NS_ERROR_NULL_POINTER; - - // make a array - nsresult res = NS_NewISupportsArray(getter_AddRefs(*outArrayOfNodes)); - if (NS_FAILED(res)) return res; - - // make an iter - nsCOMPtr iter; - res = nsComponentManager::CreateInstance(kContentIteratorCID, nsnull, - NS_GET_IID(nsIContentIterator), - getter_AddRefs(iter)); - if (NS_FAILED(res)) return res; - if (!iter) return NS_ERROR_FAILURE; - - nsCOMPtr content; - nsCOMPtr node; - nsCOMPtr isupports; - - // iterate node and build up array of non-list content - content = do_QueryInterface(aNode); - iter->Init(content); - while (NS_ENUMERATOR_FALSE == iter->IsDone()) - { - res = iter->CurrentNode(getter_AddRefs(content)); - if (NS_FAILED(res)) return res; - node = do_QueryInterface(content); - if (!node) return NS_ERROR_FAILURE; - if (nsHTMLEditUtils::IsList(node) || nsHTMLEditUtils::IsListItem(node)) + else { - nsCOMPtr child, tmp; - res = mEditor->GetFirstEditableChild(node, &child); - if (NS_FAILED(res)) return res; - while (child) - { - isupports = do_QueryInterface(child); - (*outArrayOfNodes)->AppendElement(isupports); - mEditor->GetNextHTMLSibling(child, &tmp); - child = tmp; - } + isupports = do_QueryInterface(node); + outArrayOfNodes->AppendElement(isupports); } - res = iter->Next(); - if (NS_FAILED(res)) return res; + nsCOMPtr tmp; + res = node->GetNextSibling(getter_AddRefs(tmp)); + node = tmp; } + return res; } @@ -3033,16 +3028,35 @@ nsHTMLEditRules::GetListActionNodes(nsCOMPtr *outArrayOfNodes, if (mEditor->IsTableElement(testNode) && !mEditor->IsTable(testNode)) { (*outArrayOfNodes)->RemoveElementAt(i); - nsCOMPtr arrayOfTableContent; - res = GetTableContent(testNode, &arrayOfTableContent); + res = GetInnerContent(testNode, *outArrayOfNodes, PR_FALSE); if (NS_FAILED(res)) return res; - (*outArrayOfNodes)->AppendElements(arrayOfTableContent); } } return res; } +/////////////////////////////////////////////////////////////////////////// +// GetDefinitionListItemTypes: +// +nsresult +nsHTMLEditRules::GetDefinitionListItemTypes(nsIDOMNode *aNode, PRBool &aDT, PRBool &aDD) +{ + if (!aNode) return NS_ERROR_NULL_POINTER; + aDT = aDD = PR_FALSE; + nsresult res = NS_OK; + nsCOMPtr child, temp; + res = aNode->GetFirstChild(getter_AddRefs(child)); + while (child && NS_SUCCEEDED(res)) + { + if (mEditor->NodeIsType(child,nsIEditProperty::dt)) aDT = PR_TRUE; + else if (mEditor->NodeIsType(child,nsIEditProperty::dd)) aDD = PR_TRUE; + res = child->GetNextSibling(getter_AddRefs(temp)); + child = temp; + } + return res; +} + /////////////////////////////////////////////////////////////////////////// // GetParagraphFormatNodes: // @@ -3080,22 +3094,14 @@ nsHTMLEditRules::GetParagraphFormatNodes(nsCOMPtr *outArrayOfN } // scan for table elements. If we find table elements other than table, - // replace it with a list of any editable non-table content. - if (mEditor->IsTableElement(testNode) && !mEditor->IsTable(testNode)) + // replace it with a list of any editable non-table content. Ditto for list elements. + if (mEditor->IsTableElement(testNode) || + nsHTMLEditUtils::IsList(testNode) || + nsHTMLEditUtils::IsListItem(testNode) ) { (*outArrayOfNodes)->RemoveElementAt(i); - nsCOMPtr arrayOfTableContent; - res = GetTableContent(testNode, &arrayOfTableContent); + res = GetInnerContent(testNode, *outArrayOfNodes); if (NS_FAILED(res)) return res; - (*outArrayOfNodes)->AppendElements(arrayOfTableContent); - } - else if (nsHTMLEditUtils::IsList(testNode) || nsHTMLEditUtils::IsListItem(testNode)) - { - (*outArrayOfNodes)->RemoveElementAt(i); - nsCOMPtr arrayOfTableContent; - res = GetListContent(testNode, &arrayOfTableContent); - if (NS_FAILED(res)) return res; - (*outArrayOfNodes)->AppendElements(arrayOfTableContent); } } return res; diff --git a/mozilla/editor/libeditor/html/nsHTMLEditRules.h b/mozilla/editor/libeditor/html/nsHTMLEditRules.h index c70838963fe..dbb5ecf9521 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditRules.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditRules.h @@ -53,7 +53,8 @@ public: NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); // nsIHTMLEditRules methods - NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL); + NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL); + NS_IMETHOD GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD); NS_IMETHOD GetIndentState(PRBool &aCanIndent, PRBool &aCanOutdent); NS_IMETHOD GetParagraphState(PRBool &aMixed, nsString &outFormat); @@ -109,8 +110,7 @@ protected: nsresult AlignTableElement(nsIDOMNode *aNode, const nsString *alignType); nsresult AlignTableCellContents(nsIDOMNode *aNode, const nsString *alignType); - nsresult GetTableContent(nsIDOMNode *aNode, nsCOMPtr *outArrayOfNodes); - nsresult GetListContent(nsIDOMNode *aNode, nsCOMPtr *outArrayOfNodes); + nsresult GetInnerContent(nsIDOMNode *aNode, nsISupportsArray *outArrayOfNodes, PRBool aList = PR_TRUE, PRBool aTble = PR_TRUE); nsresult InsertTab(nsIDOMSelection *aSelection, nsString *outString); @@ -143,6 +143,7 @@ protected: nsresult GetChildNodesForOperation(nsIDOMNode *inNode, nsCOMPtr *outArrayOfNodes); nsresult GetListActionNodes(nsCOMPtr *outArrayOfNodes, PRBool aDontTouchContent=PR_FALSE); + nsresult GetDefinitionListItemTypes(nsIDOMNode *aNode, PRBool &aDT, PRBool &aDD); nsresult GetParagraphFormatNodes(nsCOMPtr *outArrayOfNodes, PRBool aDontTouchContent=PR_FALSE); nsresult BustUpInlinesAtBRs(nsIDOMNode *inNode, nsCOMPtr *outArrayOfNodes); diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp index 5bd589ae42a..ba56888cf4f 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp @@ -3014,14 +3014,25 @@ nsHTMLEditor::GetFontFaceState(PRBool &aMixed, nsString &outFace) } NS_IMETHODIMP -nsHTMLEditor::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL) +nsHTMLEditor::GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL) { if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } nsCOMPtr htmlRules = do_QueryInterface(mRules); if (!htmlRules) return NS_ERROR_FAILURE; - return htmlRules->GetListState(aMixed, aOL, aUL); + return htmlRules->GetListState(aMixed, aOL, aUL, aDL); +} + +NS_IMETHODIMP +nsHTMLEditor::GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD) +{ + if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } + + nsCOMPtr htmlRules = do_QueryInterface(mRules); + if (!htmlRules) return NS_ERROR_FAILURE; + + return htmlRules->GetListItemState(aMixed, aLI, aDT, aDD); } NS_IMETHODIMP diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h index 48d3045f7a5..f9f30cce0b1 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h @@ -135,7 +135,8 @@ public: NS_IMETHOD GetParagraphState(PRBool &aMixed, nsString &outFormat); NS_IMETHOD GetFontFaceState(PRBool &aMixed, nsString &outFace); - NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL); + NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL); + NS_IMETHOD GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD); NS_IMETHOD GetIndentState(PRBool &aCanIndent, PRBool &aCanOutdent); NS_IMETHOD MakeOrChangeList(const nsString& aListType); diff --git a/mozilla/editor/libeditor/html/nsIHTMLEditRules.h b/mozilla/editor/libeditor/html/nsIHTMLEditRules.h index 141444c2ad2..092a8dfe127 100644 --- a/mozilla/editor/libeditor/html/nsIHTMLEditRules.h +++ b/mozilla/editor/libeditor/html/nsIHTMLEditRules.h @@ -33,7 +33,8 @@ class nsIHTMLEditRules : public nsISupports public: static const nsIID& GetIID() { static nsIID iid = NS_IHTMLEDITRULES_IID; return iid; } - NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL)=0; + NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL)=0; + NS_IMETHOD GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD)=0; NS_IMETHOD GetIndentState(PRBool &aCanIndent, PRBool &aCanOutdent)=0; NS_IMETHOD GetParagraphState(PRBool &aMixed, nsString &outFormat)=0; }; diff --git a/mozilla/editor/public/nsIHTMLEditor.h b/mozilla/editor/public/nsIHTMLEditor.h index 402ff7be3b3..a0092ee759e 100644 --- a/mozilla/editor/public/nsIHTMLEditor.h +++ b/mozilla/editor/public/nsIHTMLEditor.h @@ -297,8 +297,19 @@ public: * @param aOL The company that employs me. No, really, it's * true if an "ol" list is selected. * @param aUL true if an "ul" list is selected. + * @param aDL true if a "dl" list is selected. */ - NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL)=0; + NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL)=0; + + /** + * GetListItemState returns what list item type is in the selection. + * @param aMixed True if there is more than one type of list item, or + * if there is some list and non-list + * @param aLI true if "li" list items are selected. + * @param aDT true if "dt" list items are selected. + * @param aDD true if "dd" list items are selected. + */ + NS_IMETHOD GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD)=0; /** * Document me!