From bef7afc6f339af29de5bbd78bafa86d7fb158d14 Mon Sep 17 00:00:00 2001 From: "glazman%netscape.com" Date: Tue, 17 Jun 2003 08:45:54 +0000 Subject: [PATCH] Removing text styles in CSS mode was potentially removing too much if the styles were added in HTML mode The fix creates a span element that will carry the inline styles and class of the HTML element to be removed, if any. b=202037, r=kaie, sr=dmose --- editor/idl/nsIEditor.idl | 15 +++++++++++ editor/libeditor/base/nsEditor.cpp | 30 +++++++++++++++++++++ editor/libeditor/html/nsHTMLEditorStyle.cpp | 21 +++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/editor/idl/nsIEditor.idl b/editor/idl/nsIEditor.idl index 4a1a091e2ba..e838091c200 100644 --- a/editor/idl/nsIEditor.idl +++ b/editor/idl/nsIEditor.idl @@ -373,6 +373,21 @@ interface nsIEditor : nsISupports void removeAttribute(in nsIDOMElement aElement, in AString aAttribute); + /** + * cloneAttribute() copies the attribute from the source node to + * the destination node and delete those not in the source. + * + * The supplied nodes MUST BE ELEMENTS (most callers are working with nodes) + * @param aAttribute the name of the attribute to copy + * @param aDestNode the destination element to operate on + * @param aSourceNode the source element to copy attributes from + * @exception NS_ERROR_NULL_POINTER at least one of the nodes is null + * @exception NS_ERROR_NO_INTERFACE at least one of the nodes is not an + * element + */ + void cloneAttribute(in AString aAttribute, + in nsIDOMNode aDestNode, in nsIDOMNode aSourceNode); + /** * cloneAttributes() is similar to nsIDOMNode::cloneNode(), * it assures the attribute nodes of the destination are identical diff --git a/editor/libeditor/base/nsEditor.cpp b/editor/libeditor/base/nsEditor.cpp index a98b45d624e..a716baa222e 100644 --- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -2223,6 +2223,36 @@ nsEditor::EndOperation() return NS_OK; } +NS_IMETHODIMP +nsEditor::CloneAttribute(const nsAString & aAttribute, + nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode) +{ + nsresult rv = NS_OK; + + if (!aDestNode || !aSourceNode) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr destElement = do_QueryInterface(aDestNode); + nsCOMPtr sourceElement = do_QueryInterface(aSourceNode); + if (!destElement || !sourceElement) + return NS_ERROR_NO_INTERFACE; + + nsAutoString attrValue; + PRBool isAttrSet; + rv = GetAttributeValue(sourceElement, + aAttribute, + attrValue, + &isAttrSet); + if (NS_FAILED(rv)) + return rv; + if (isAttrSet) + rv = SetAttribute(destElement, aAttribute, attrValue); + else + rv = RemoveAttribute(destElement, aAttribute); + + return rv; +} + // Objects must be DOM elements NS_IMETHODIMP nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode) diff --git a/editor/libeditor/html/nsHTMLEditorStyle.cpp b/editor/libeditor/html/nsHTMLEditorStyle.cpp index 1c1d5d2e6d8..bc51a37f4c1 100644 --- a/editor/libeditor/html/nsHTMLEditorStyle.cpp +++ b/editor/libeditor/html/nsHTMLEditorStyle.cpp @@ -691,6 +691,27 @@ nsresult nsHTMLEditor::RemoveStyleInside(nsIDOMNode *aNode, // remove any matching inlinestyles entirely if (!aAttribute || aAttribute->IsEmpty()) { + NS_NAMED_LITERAL_STRING(styleAttr, "style"); + NS_NAMED_LITERAL_STRING(classAttr, "class"); + PRBool hasStyleAttr = HasAttr(aNode, &styleAttr); + PRBool hasClassAtrr = HasAttr(aNode, &classAttr); + if (hasStyleAttr || hasClassAtrr) { + // aNode carries inline styles or a class attribute so we can't + // just remove the element... We need to create above the element + // a span that will carry those styles or class, then we can delete + // the node. + nsCOMPtr spanNode; + res = InsertContainerAbove(aNode, address_of(spanNode), + NS_LITERAL_STRING("span")); + if (NS_FAILED(res)) + return res; + res = CloneAttribute(styleAttr, spanNode, aNode); + if (NS_FAILED(res)) + return res; + res = CloneAttribute(classAttr, spanNode, aNode); + if (NS_FAILED(res)) + return res; + } res = RemoveContainer(aNode); } // otherwise we just want to eliminate the attribute