From 3db2c2bdfbcd622e35d9dfb4d4c84aff6738716e Mon Sep 17 00:00:00 2001 From: "glazman%netscape.com" Date: Tue, 15 Jan 2002 14:44:00 +0000 Subject: [PATCH] [CSS] Composer should be able to unbold/unitalicize invalid markup; b=119447, r=jfrancis, sr=kin git-svn-id: svn://10.0.0.236/trunk@112170 18797224-902f-48f8-a5cc-f745e15eee43 --- .../editor/libeditor/html/nsHTMLCSSUtils.cpp | 23 +++++- mozilla/editor/libeditor/html/nsHTMLEditor.h | 2 + .../libeditor/html/nsHTMLEditorStyle.cpp | 77 ++++++++++++++----- 3 files changed, 82 insertions(+), 20 deletions(-) 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; +}