diff --git a/mozilla/editor/base/TypeInState.cpp b/mozilla/editor/base/TypeInState.cpp index 989a8da4540..06bf27cfff9 100644 --- a/mozilla/editor/base/TypeInState.cpp +++ b/mozilla/editor/base/TypeInState.cpp @@ -154,8 +154,11 @@ nsresult TypeInState::ClearProp(nsIAtom *aProp, const nsString &aAttr, const nsS } - -nsresult TypeInState::ProcessClearProperty(PropItem **outPropItem) +/*************************************************************************** + * TakeClearProperty: hands back next poroperty item on the clear list. + * caller assumes ownership of PropItem and must delete it. + */ +nsresult TypeInState::TakeClearProperty(PropItem **outPropItem) { if (!outPropItem) return NS_ERROR_NULL_POINTER; *outPropItem = nsnull; @@ -169,8 +172,11 @@ nsresult TypeInState::ProcessClearProperty(PropItem **outPropItem) return NS_OK; } - -nsresult TypeInState::ProcessSetProperty(PropItem **outPropItem) +/*************************************************************************** + * TakeSetProperty: hands back next poroperty item on the set list. + * caller assumes ownership of PropItem and must delete it. + */ +nsresult TypeInState::TakeSetProperty(PropItem **outPropItem) { if (!outPropItem) return NS_ERROR_NULL_POINTER; *outPropItem = nsnull; @@ -271,6 +277,7 @@ PRBool TypeInState::IsPropSet(nsIAtom *aProp, const nsString &aValue, PRInt32 &outIndex) { + // linear search. list should be short. PRInt32 i, count = mSetArray.Count(); for (i=0; itag == aProp) && (item->attr == aAttr) ) { diff --git a/mozilla/editor/base/TypeInState.h b/mozilla/editor/base/TypeInState.h index f021f879b28..39b782dc2b4 100644 --- a/mozilla/editor/base/TypeInState.h +++ b/mozilla/editor/base/TypeInState.h @@ -53,12 +53,20 @@ public: nsresult SetProp(nsIAtom *aProp); nsresult SetProp(nsIAtom *aProp, const nsString &aAttr); nsresult SetProp(nsIAtom *aProp, const nsString &aAttr, const nsString &aValue); + nsresult ClearProp(nsIAtom *aProp); nsresult ClearProp(nsIAtom *aProp, const nsString &aAttr); nsresult ClearProp(nsIAtom *aProp, const nsString &aAttr, const nsString &aValue); - nsresult ProcessClearProperty(PropItem **outPropItem); - nsresult ProcessSetProperty(PropItem **outPropItem); + //************************************************************************** + // TakeClearProperty: hands back next poroperty item on the clear list. + // caller assumes ownership of PropItem and must delete it. + nsresult TakeClearProperty(PropItem **outPropItem); + + //************************************************************************** + // TakeSetProperty: hands back next poroperty item on the set list. + // caller assumes ownership of PropItem and must delete it. + nsresult TakeSetProperty(PropItem **outPropItem); nsresult GetTypingState(PRBool &isSet, PRBool &theSetting, nsIAtom *aProp); nsresult GetTypingState(PRBool &isSet, PRBool &theSetting, nsIAtom *aProp, @@ -81,5 +89,5 @@ protected: -#endif // TypeInState_h__ +#endif // TypeInState_h__ diff --git a/mozilla/editor/base/nsHTMLEditRules.cpp b/mozilla/editor/base/nsHTMLEditRules.cpp index 5eda511cffe..3975d6b827e 100644 --- a/mozilla/editor/base/nsHTMLEditRules.cpp +++ b/mozilla/editor/base/nsHTMLEditRules.cpp @@ -313,9 +313,15 @@ NS_IMETHODIMP nsHTMLEditRules::DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult) { - // pass thru to nsTextEditRules: - nsresult res = nsTextEditRules::DidDoAction(aSelection, aInfo, aResult); - return res; + nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo); + switch (info->action) + { + case kMakeBasicBlock: + return DidMakeBasicBlock(aSelection, aInfo, aResult); + } + + // default: pass thru to nsTextEditRules + return nsTextEditRules::DidDoAction(aSelection, aInfo, aResult); } @@ -1472,6 +1478,24 @@ nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection, return res; } +NS_IMETHODIMP +nsHTMLEditRules::DidMakeBasicBlock(nsIDOMSelection *aSelection, + nsRulesInfo *aInfo, nsresult aResult) +{ + if (!aSelection) return NS_ERROR_NULL_POINTER; + // check for empty block. if so, put a moz br in it. + PRBool isCollapsed; + nsresult res = aSelection->GetIsCollapsed(&isCollapsed); + if (NS_FAILED(res)) return res; + if (!isCollapsed) return NS_OK; + + nsCOMPtr parent; + PRInt32 offset; + res = nsEditor::GetStartNodeAndOffset(aSelection, &parent, &offset); + if (NS_FAILED(res)) return res; + res = InsertMozBRIfNeeded(parent); + return res; +} nsresult nsHTMLEditRules::WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool * aHandled) @@ -1710,18 +1734,18 @@ nsHTMLEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, nsIDOMDoc PropItem *item = nsnull; // process clearing any styles first - mEditor->mTypeInState->ProcessClearProperty(&item); + mEditor->mTypeInState->TakeClearProperty(&item); while (item) { res = mEditor->SplitStyleAbovePoint(&node, &offset, item->tag, &item->attr); if (NS_FAILED(res)) return res; - // we own item now (ProcessClearProperty hands ownership to us) + // we own item now (TakeClearProperty hands ownership to us) delete item; - mEditor->mTypeInState->ProcessClearProperty(&item); + mEditor->mTypeInState->TakeClearProperty(&item); } // then process setting any styles - mEditor->mTypeInState->ProcessSetProperty(&item); + mEditor->mTypeInState->TakeSetProperty(&item); if (item) // we have at least one style to add; make a { // new text node to insert style nodes above. @@ -1750,9 +1774,9 @@ nsHTMLEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, nsIDOMDoc { res = mEditor->SetInlinePropertyOnNode(node, item->tag, &item->attr, &item->value); if (NS_FAILED(res)) return res; - // we own item now (ProcessSetProperty hands ownership to us) + // we own item now (TakeSetProperty hands ownership to us) delete item; - mEditor->mTypeInState->ProcessSetProperty(&item); + mEditor->mTypeInState->TakeSetProperty(&item); } return aSelection->Collapse(node, offset); @@ -2883,6 +2907,16 @@ nsHTMLEditRules::ReturnInParagraph(nsIDOMSelection *aSelection, // get rid of the break res = mEditor->DeleteNode(sibling); if (NS_FAILED(res)) return res; + // check both halves of para to see if we need mozBR + res = InsertMozBRIfNeeded(aPara); + if (NS_FAILED(res)) return res; + res = mEditor->GetPriorHTMLSibling(aPara, &sibling); + if (NS_FAILED(res)) return res; + if (sibling && nsHTMLEditUtils::IsParagraph(sibling)) + { + res = InsertMozBRIfNeeded(sibling); + if (NS_FAILED(res)) return res; + } // position selection inside right hand para res = aSelection->Collapse(aPara,0); } @@ -4255,7 +4289,22 @@ nsHTMLEditRules::IsDescendantOfBody(nsIDOMNode *inNode) return PR_FALSE; } - +nsresult +nsHTMLEditRules::InsertMozBRIfNeeded(nsIDOMNode *aNode) +{ + if (!aNode) return NS_ERROR_NULL_POINTER; + if (!mEditor->IsBlockNode(aNode)) return NS_OK; + + PRBool isEmpty; + nsCOMPtr brNode; + nsresult res = IsEmptyNode(aNode, &isEmpty); + if (NS_FAILED(res)) return res; + if (isEmpty) + { + res = CreateMozBR(aNode, 0, &brNode); + } + return res; +} #ifdef XP_MAC #pragma mark - diff --git a/mozilla/editor/base/nsHTMLEditRules.h b/mozilla/editor/base/nsHTMLEditRules.h index 9d969c7a735..1d03567e9e2 100644 --- a/mozilla/editor/base/nsHTMLEditRules.h +++ b/mozilla/editor/base/nsHTMLEditRules.h @@ -95,6 +95,7 @@ protected: nsresult WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled); nsresult WillAlign(nsIDOMSelection *aSelection, const nsString *alignType, PRBool *aCancel, PRBool *aHandled); nsresult WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString *aBlockType, PRBool *aCancel, PRBool *aHandled); + nsresult DidMakeBasicBlock(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); nsresult AlignTableElement(nsIDOMNode *aNode, const nsString *alignType); nsresult AlignTableCellContents(nsIDOMNode *aNode, const nsString *alignType); @@ -160,7 +161,8 @@ protected: nsresult ConvertWhitespace(const nsString & inString, nsString & outString); nsresult ConfirmSelectionInBody(); - PRBool IsDescendantOfBody(nsIDOMNode *inNode) ; + PRBool IsDescendantOfBody(nsIDOMNode *inNode); + nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode); // data members protected: diff --git a/mozilla/editor/base/nsTextEditRules.cpp b/mozilla/editor/base/nsTextEditRules.cpp index 0fff1af0a64..064b92260e6 100644 --- a/mozilla/editor/base/nsTextEditRules.cpp +++ b/mozilla/editor/base/nsTextEditRules.cpp @@ -588,10 +588,7 @@ nsTextEditRules::WillInsertText(PRInt32 aAction, // fixes bug 21032 // *** there's some debate about whether we should replace CRLF with spaces, or // truncate the string at the first CRLF. Here, we replace with spaces. - // Hack: I stripped out this test for IME inserts - it screws up double byte chars - // that happen to end in the same values as CR or LF. Bug 27699 - if (inString->IsEmpty() && (aAction != kInsertTextIME)) - if ((nsIHTMLEditor::eEditorSingleLineMask & mFlags) && (aAction != kInsertTextIME)) + if (nsIHTMLEditor::eEditorSingleLineMask & mFlags) { outString->ReplaceChar(CRLF, ' '); } diff --git a/mozilla/editor/libeditor/html/TypeInState.cpp b/mozilla/editor/libeditor/html/TypeInState.cpp index 989a8da4540..06bf27cfff9 100644 --- a/mozilla/editor/libeditor/html/TypeInState.cpp +++ b/mozilla/editor/libeditor/html/TypeInState.cpp @@ -154,8 +154,11 @@ nsresult TypeInState::ClearProp(nsIAtom *aProp, const nsString &aAttr, const nsS } - -nsresult TypeInState::ProcessClearProperty(PropItem **outPropItem) +/*************************************************************************** + * TakeClearProperty: hands back next poroperty item on the clear list. + * caller assumes ownership of PropItem and must delete it. + */ +nsresult TypeInState::TakeClearProperty(PropItem **outPropItem) { if (!outPropItem) return NS_ERROR_NULL_POINTER; *outPropItem = nsnull; @@ -169,8 +172,11 @@ nsresult TypeInState::ProcessClearProperty(PropItem **outPropItem) return NS_OK; } - -nsresult TypeInState::ProcessSetProperty(PropItem **outPropItem) +/*************************************************************************** + * TakeSetProperty: hands back next poroperty item on the set list. + * caller assumes ownership of PropItem and must delete it. + */ +nsresult TypeInState::TakeSetProperty(PropItem **outPropItem) { if (!outPropItem) return NS_ERROR_NULL_POINTER; *outPropItem = nsnull; @@ -271,6 +277,7 @@ PRBool TypeInState::IsPropSet(nsIAtom *aProp, const nsString &aValue, PRInt32 &outIndex) { + // linear search. list should be short. PRInt32 i, count = mSetArray.Count(); for (i=0; itag == aProp) && (item->attr == aAttr) ) { diff --git a/mozilla/editor/libeditor/html/TypeInState.h b/mozilla/editor/libeditor/html/TypeInState.h index f021f879b28..39b782dc2b4 100644 --- a/mozilla/editor/libeditor/html/TypeInState.h +++ b/mozilla/editor/libeditor/html/TypeInState.h @@ -53,12 +53,20 @@ public: nsresult SetProp(nsIAtom *aProp); nsresult SetProp(nsIAtom *aProp, const nsString &aAttr); nsresult SetProp(nsIAtom *aProp, const nsString &aAttr, const nsString &aValue); + nsresult ClearProp(nsIAtom *aProp); nsresult ClearProp(nsIAtom *aProp, const nsString &aAttr); nsresult ClearProp(nsIAtom *aProp, const nsString &aAttr, const nsString &aValue); - nsresult ProcessClearProperty(PropItem **outPropItem); - nsresult ProcessSetProperty(PropItem **outPropItem); + //************************************************************************** + // TakeClearProperty: hands back next poroperty item on the clear list. + // caller assumes ownership of PropItem and must delete it. + nsresult TakeClearProperty(PropItem **outPropItem); + + //************************************************************************** + // TakeSetProperty: hands back next poroperty item on the set list. + // caller assumes ownership of PropItem and must delete it. + nsresult TakeSetProperty(PropItem **outPropItem); nsresult GetTypingState(PRBool &isSet, PRBool &theSetting, nsIAtom *aProp); nsresult GetTypingState(PRBool &isSet, PRBool &theSetting, nsIAtom *aProp, @@ -81,5 +89,5 @@ protected: -#endif // TypeInState_h__ +#endif // TypeInState_h__ diff --git a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp index 5eda511cffe..3975d6b827e 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp @@ -313,9 +313,15 @@ NS_IMETHODIMP nsHTMLEditRules::DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult) { - // pass thru to nsTextEditRules: - nsresult res = nsTextEditRules::DidDoAction(aSelection, aInfo, aResult); - return res; + nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo); + switch (info->action) + { + case kMakeBasicBlock: + return DidMakeBasicBlock(aSelection, aInfo, aResult); + } + + // default: pass thru to nsTextEditRules + return nsTextEditRules::DidDoAction(aSelection, aInfo, aResult); } @@ -1472,6 +1478,24 @@ nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection, return res; } +NS_IMETHODIMP +nsHTMLEditRules::DidMakeBasicBlock(nsIDOMSelection *aSelection, + nsRulesInfo *aInfo, nsresult aResult) +{ + if (!aSelection) return NS_ERROR_NULL_POINTER; + // check for empty block. if so, put a moz br in it. + PRBool isCollapsed; + nsresult res = aSelection->GetIsCollapsed(&isCollapsed); + if (NS_FAILED(res)) return res; + if (!isCollapsed) return NS_OK; + + nsCOMPtr parent; + PRInt32 offset; + res = nsEditor::GetStartNodeAndOffset(aSelection, &parent, &offset); + if (NS_FAILED(res)) return res; + res = InsertMozBRIfNeeded(parent); + return res; +} nsresult nsHTMLEditRules::WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool * aHandled) @@ -1710,18 +1734,18 @@ nsHTMLEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, nsIDOMDoc PropItem *item = nsnull; // process clearing any styles first - mEditor->mTypeInState->ProcessClearProperty(&item); + mEditor->mTypeInState->TakeClearProperty(&item); while (item) { res = mEditor->SplitStyleAbovePoint(&node, &offset, item->tag, &item->attr); if (NS_FAILED(res)) return res; - // we own item now (ProcessClearProperty hands ownership to us) + // we own item now (TakeClearProperty hands ownership to us) delete item; - mEditor->mTypeInState->ProcessClearProperty(&item); + mEditor->mTypeInState->TakeClearProperty(&item); } // then process setting any styles - mEditor->mTypeInState->ProcessSetProperty(&item); + mEditor->mTypeInState->TakeSetProperty(&item); if (item) // we have at least one style to add; make a { // new text node to insert style nodes above. @@ -1750,9 +1774,9 @@ nsHTMLEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, nsIDOMDoc { res = mEditor->SetInlinePropertyOnNode(node, item->tag, &item->attr, &item->value); if (NS_FAILED(res)) return res; - // we own item now (ProcessSetProperty hands ownership to us) + // we own item now (TakeSetProperty hands ownership to us) delete item; - mEditor->mTypeInState->ProcessSetProperty(&item); + mEditor->mTypeInState->TakeSetProperty(&item); } return aSelection->Collapse(node, offset); @@ -2883,6 +2907,16 @@ nsHTMLEditRules::ReturnInParagraph(nsIDOMSelection *aSelection, // get rid of the break res = mEditor->DeleteNode(sibling); if (NS_FAILED(res)) return res; + // check both halves of para to see if we need mozBR + res = InsertMozBRIfNeeded(aPara); + if (NS_FAILED(res)) return res; + res = mEditor->GetPriorHTMLSibling(aPara, &sibling); + if (NS_FAILED(res)) return res; + if (sibling && nsHTMLEditUtils::IsParagraph(sibling)) + { + res = InsertMozBRIfNeeded(sibling); + if (NS_FAILED(res)) return res; + } // position selection inside right hand para res = aSelection->Collapse(aPara,0); } @@ -4255,7 +4289,22 @@ nsHTMLEditRules::IsDescendantOfBody(nsIDOMNode *inNode) return PR_FALSE; } - +nsresult +nsHTMLEditRules::InsertMozBRIfNeeded(nsIDOMNode *aNode) +{ + if (!aNode) return NS_ERROR_NULL_POINTER; + if (!mEditor->IsBlockNode(aNode)) return NS_OK; + + PRBool isEmpty; + nsCOMPtr brNode; + nsresult res = IsEmptyNode(aNode, &isEmpty); + if (NS_FAILED(res)) return res; + if (isEmpty) + { + res = CreateMozBR(aNode, 0, &brNode); + } + return res; +} #ifdef XP_MAC #pragma mark - diff --git a/mozilla/editor/libeditor/html/nsHTMLEditRules.h b/mozilla/editor/libeditor/html/nsHTMLEditRules.h index 9d969c7a735..1d03567e9e2 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditRules.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditRules.h @@ -95,6 +95,7 @@ protected: nsresult WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled); nsresult WillAlign(nsIDOMSelection *aSelection, const nsString *alignType, PRBool *aCancel, PRBool *aHandled); nsresult WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString *aBlockType, PRBool *aCancel, PRBool *aHandled); + nsresult DidMakeBasicBlock(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); nsresult AlignTableElement(nsIDOMNode *aNode, const nsString *alignType); nsresult AlignTableCellContents(nsIDOMNode *aNode, const nsString *alignType); @@ -160,7 +161,8 @@ protected: nsresult ConvertWhitespace(const nsString & inString, nsString & outString); nsresult ConfirmSelectionInBody(); - PRBool IsDescendantOfBody(nsIDOMNode *inNode) ; + PRBool IsDescendantOfBody(nsIDOMNode *inNode); + nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode); // data members protected: diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.cpp b/mozilla/editor/libeditor/text/nsTextEditRules.cpp index 0fff1af0a64..064b92260e6 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.cpp +++ b/mozilla/editor/libeditor/text/nsTextEditRules.cpp @@ -588,10 +588,7 @@ nsTextEditRules::WillInsertText(PRInt32 aAction, // fixes bug 21032 // *** there's some debate about whether we should replace CRLF with spaces, or // truncate the string at the first CRLF. Here, we replace with spaces. - // Hack: I stripped out this test for IME inserts - it screws up double byte chars - // that happen to end in the same values as CR or LF. Bug 27699 - if (inString->IsEmpty() && (aAction != kInsertTextIME)) - if ((nsIHTMLEditor::eEditorSingleLineMask & mFlags) && (aAction != kInsertTextIME)) + if (nsIHTMLEditor::eEditorSingleLineMask & mFlags) { outString->ReplaceChar(CRLF, ' '); }