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;
+}