diff --git a/mozilla/editor/libeditor/html/nsHTMLCSSUtils.cpp b/mozilla/editor/libeditor/html/nsHTMLCSSUtils.cpp index 0e086971dfc..6cee18abeed 100644 --- a/mozilla/editor/libeditor/html/nsHTMLCSSUtils.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLCSSUtils.cpp @@ -74,6 +74,24 @@ void ProcessBValue(nsAReadableString * aInputString, nsAWritableString & aOutput } } +static +void ProcessIValue(nsAReadableString * aInputString, nsAWritableString & aOutputString, + const char * aDefaultValueString, + const char * aPrependString, const char* aAppendString) +{ + if (aInputString) { + if (aInputString->Equals(NS_LITERAL_STRING("-moz-editor-invert-value"))) { + aOutputString.Assign(NS_LITERAL_STRING("normal")); + } + else { + aOutputString.Assign(NS_LITERAL_STRING("italic")); + } + } + else { + aOutputString.Assign(NS_LITERAL_STRING("italic")); + } +} + static void ProcessDefaultValue(nsAReadableString * aInputString, nsAWritableString & aOutputString, const char * aDefaultValueString, @@ -205,7 +223,7 @@ const nsHTMLCSSUtils::CSSEquivTable boldEquivTable[] = { }; const nsHTMLCSSUtils::CSSEquivTable italicEquivTable[] = { - { nsHTMLCSSUtils::eCSSEditableProperty_font_style, ProcessDefaultValue, "italic", nsnull, nsnull, PR_TRUE }, + { nsHTMLCSSUtils::eCSSEditableProperty_font_style, ProcessIValue, nsnull, nsnull, nsnull, PR_TRUE }, { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 } }; @@ -643,7 +661,8 @@ nsHTMLCSSUtils::RemoveCSSInlineStyle(nsIDOMNode *aNode, nsIAtom *aProperty, nsAR PRBool nsHTMLCSSUtils::IsCSSInvertable(nsIAtom *aProperty, const nsAReadableString *aAttribute) { - return PRBool(nsIEditProperty::b == aProperty); + return PRBool(nsIEditProperty::b == aProperty + || nsIEditProperty::i == aProperty); } // Get the default browser background color if we need it for GetCSSBackgroundColorState diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h index 70f35957b95..82d5a847632 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h @@ -719,6 +719,8 @@ protected: PRBool *aAll, nsAWritableString *outValue); + nsresult RemoveElementIfUselessSpan(nsIDOMElement * aElement); + // Data members protected: diff --git a/mozilla/editor/libeditor/html/nsHTMLEditorStyle.cpp b/mozilla/editor/libeditor/html/nsHTMLEditorStyle.cpp index bd0d0919e03..d7a7545886f 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditorStyle.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditorStyle.cpp @@ -334,7 +334,11 @@ nsHTMLEditor::SetInlinePropertyOnTextNode( nsIDOMCharacterData *aTextNode, PRBool bHasProp; nsCOMPtr styleNode; IsTextPropertySetByContent(node, aProperty, aAttribute, aValue, bHasProp, getter_AddRefs(styleNode)); - if (bHasProp) return NS_OK; + if (bHasProp && + !(aValue && aValue->Equals(NS_LITERAL_STRING("-moz-editor-invert-value")))) + { + return NS_OK; + } // do we need to split the text node? PRUint32 textLen; @@ -420,10 +424,32 @@ nsHTMLEditor::SetInlinePropertyOnNode( nsIDOMNode *aNode, // children of the aNode res = RemoveStyleInside(tmp, aProperty, aAttribute, PR_TRUE); if (NS_FAILED(res)) return res; - PRInt32 count; - // then we add the css styles corresponding to the HTML style request - res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, aProperty, aAttribute, aValue, &count); + nsCOMPtr parentNode; + res = tmp->GetParentNode(getter_AddRefs(parentNode)); if (NS_FAILED(res)) return res; + PRBool isSet = PR_FALSE; + if (parentNode) { + // let's check if the parent element already has the style we want + nsAutoString parentValue; + mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(parentNode, aProperty, aAttribute, + isSet, parentValue, + COMPUTED_STYLE_TYPE); + } + if (isSet && !(aValue && aValue->Equals(NS_LITERAL_STRING("-moz-editor-invert-value")))) { + // the parent has the style we want to apply and we are not trying to remove this style + // from the selection + res = mHTMLCSSUtils->RemoveCSSEquivalentToHTMLStyle(element, + aProperty, + aAttribute, + aValue); + if (NS_FAILED(res)) return res; + res = RemoveElementIfUselessSpan(element); + } + else { + PRInt32 count; + // add the css styles corresponding to the HTML style request + res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, aProperty, aAttribute, aValue, &count); + } return res; } } @@ -695,21 +721,9 @@ nsresult nsHTMLEditor::RemoveStyleInside(nsIDOMNode *aNode, aProperty, aAttribute, &propertyValue); - // remove the node if it is a span, if its style attribute is empty or absent, - // and if it does not have a class nor an id - nsCOMPtr elem = do_QueryInterface(aNode); - nsAutoString styleVal; - PRBool isStyleSet; - res = GetAttributeValue(elem, NS_LITERAL_STRING("style"), styleVal, &isStyleSet); + nsCOMPtr element = do_QueryInterface(aNode); + res = RemoveElementIfUselessSpan(element); if (NS_FAILED(res)) return res; - if (NodeIsType(aNode, nsIEditProperty::span) && (!isStyleSet || (0 == styleVal.Length()))) { - PRBool hasClassOrId ; - res = mHTMLCSSUtils->HasClassOrID(elem, hasClassOrId); - if (!hasClassOrId) { - res = RemoveContainer(aNode); - if (NS_FAILED(res)) return res; - } - } } } } @@ -1822,3 +1836,30 @@ nsHTMLEditor::IsCSSEnabled(PRBool *aIsSet) return NS_OK; } +nsresult +nsHTMLEditor::RemoveElementIfUselessSpan(nsIDOMElement * aElement) +{ + NS_ENSURE_TRUE(aElement, NS_ERROR_NULL_POINTER); + nsCOMPtr node = do_QueryInterface(aElement); + + // early way out if node is not a span element + if (!NodeIsType(node, nsIEditProperty::span)) { + return NS_OK; + } + + // remove the node if it is a span, if its style attribute is empty or absent, + // and if it does not have a class nor an id + nsAutoString styleVal; + PRBool isStyleSet; + nsresult res = GetAttributeValue(aElement, NS_LITERAL_STRING("style"), styleVal, &isStyleSet); + if (NS_FAILED(res)) return res; + if (!isStyleSet || (0 == styleVal.Length())) { + PRBool hasClassOrId ; + res = mHTMLCSSUtils->HasClassOrID(aElement, hasClassOrId); + if (NS_FAILED(res)) return res; + if (!hasClassOrId) { + res = RemoveContainer(node); + } + } + return res; +}