Fix innerHTML on some special elements to suck less; refactor some

code.  Bug 125746, r=sicking, sr=jst


git-svn-id: svn://10.0.0.236/trunk@124666 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzbarsky%mit.edu 2002-07-04 04:30:25 +00:00
parent f29a33f656
commit 5483f8d08e
8 changed files with 177 additions and 118 deletions

View File

@ -132,6 +132,9 @@
#include "nsHTMLUtils.h"
#include "nsIDOMText.h"
#include "nsITextContent.h"
static NS_DEFINE_CID(kPresStateCID, NS_PRESSTATE_CID);
// XXX todo: add in missing out-of-memory checks
@ -4145,6 +4148,73 @@ nsGenericHTMLContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
return NS_OK;
}
nsresult
nsGenericHTMLContainerElement::ReplaceContentsWithText(const nsAString& aText,
PRBool aNotify) {
PRInt32 children;
nsresult rv = ChildCount(children);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> firstChild;
nsCOMPtr<nsIDOMText> textChild;
// if we already have a DOMText child, reuse it.
if (children > 0) {
rv = ChildAt(0, *getter_AddRefs(firstChild));
NS_ENSURE_SUCCESS(rv, rv);
textChild = do_QueryInterface(firstChild);
}
PRInt32 i;
PRInt32 lastChild = textChild ? 1 : 0;
for (i = children - 1; i >= lastChild; --i) {
RemoveChildAt(i, aNotify);
}
if (!textChild) {
nsCOMPtr<nsIContent> text;
rv = NS_NewTextNode(getter_AddRefs(text));
NS_ENSURE_SUCCESS(rv, rv);
textChild = do_QueryInterface(text);
NS_ASSERTION(textChild, "NS_NewTextNode returned something not implementing nsIDOMText!");
rv = textChild->SetData(aText);
NS_ENSURE_SUCCESS(rv, rv);
rv = InsertChildAt(text, 0, aNotify, PR_FALSE);
} else {
rv = textChild->SetData(aText);
}
return rv;
}
nsresult
nsGenericHTMLContainerElement::GetContentsAsText(nsAString& aText)
{
aText.Truncate();
PRInt32 children;
nsresult rv = ChildCount(children);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMText> tc;
nsCOMPtr<nsIContent> child;
nsAutoString textData;
PRInt32 i;
for (i = 0; i < children; ++i) {
ChildAt(i, *getter_AddRefs(child));
tc = do_QueryInterface(child);
if (tc) {
if (aText.IsEmpty()) {
tc->GetData(aText);
} else {
tc->GetData(textData);
aText.Append(textData);
}
}
}
return NS_OK;
}
//----------------------------------------------------------------------
nsGenericHTMLContainerFormElement::nsGenericHTMLContainerFormElement()

View File

@ -128,8 +128,8 @@ public:
nsresult GetOffsetWidth(PRInt32* aOffsetWidth);
nsresult GetOffsetHeight(PRInt32* aOffsetHeight);
nsresult GetOffsetParent(nsIDOMElement** aOffsetParent);
nsresult GetInnerHTML(nsAString& aInnerHTML);
nsresult SetInnerHTML(const nsAString& aInnerHTML);
virtual nsresult GetInnerHTML(nsAString& aInnerHTML);
virtual nsresult SetInnerHTML(const nsAString& aInnerHTML);
nsresult GetScrollTop(PRInt32* aScrollTop);
nsresult SetScrollTop(PRInt32 aScrollTop);
nsresult GetScrollLeft(PRInt32* aScrollLeft);
@ -644,6 +644,21 @@ public:
NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify);
nsSmallVoidArray mChildren;
protected:
/**
* ReplaceContentsWithText will take the aText string and make sure
* that the only child of |this| is a textnode which corresponds to
* that string.
*/
nsresult ReplaceContentsWithText(const nsAString& aText, PRBool aNotify);
/**
* GetContentsAsText will take all the textnodes that are children
* of |this| and concatenate the text in them into aText. It
* completely ignores any non-text-node children of |this|; in
* particular it does not descend into any children of |this| that
* happen to be container elements.
*/
nsresult GetContentsAsText(nsAString& aText);
};
//----------------------------------------------------------------------

View File

@ -229,6 +229,7 @@ HTML_ATOM(p, "p")
HTML_ATOM(pagex, "pagex")
HTML_ATOM(pagey, "pagey")
HTML_ATOM(param, "param")
HTML_ATOM(plaintext, "plaintext")
HTML_ATOM(pointSize, "point-size")
HTML_ATOM(pre, "pre")
HTML_ATOM(profile, "profile")
@ -308,6 +309,7 @@ HTML_ATOM(wbr, "wbr")
HTML_ATOM(width, "width")
HTML_ATOM(wrap, "wrap")
HTML_ATOM(wrappedFramePseudo, ":-moz-wrapped-frame")
HTML_ATOM(xmp, "xmp")
HTML_ATOM(zindex, "zindex")
HTML_ATOM(z_index, "z-index")

View File

@ -91,6 +91,9 @@ public:
NS_IMETHOD AppendChildTo(nsIContent* aKid, PRBool aNotify,
PRBool aDeepSetDocument);
NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML);
#ifdef DEBUG
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
#endif
@ -253,65 +256,13 @@ nsHTMLScriptElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
NS_IMETHODIMP
nsHTMLScriptElement::GetText(nsAString& aValue)
{
PRInt32 i, count = 0;
nsresult rv = NS_OK;
aValue.Truncate();
ChildCount(count);
for (i = 0; i < count; i++) {
nsCOMPtr<nsIContent> child;
rv = ChildAt(i, *getter_AddRefs(child));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(child));
if (node) {
nsAutoString tmp;
node->GetNodeValue(tmp);
aValue.Append(tmp);
}
}
return NS_OK;
return GetContentsAsText(aValue);
}
NS_IMETHODIMP
nsHTMLScriptElement::SetText(const nsAString& aValue)
{
nsCOMPtr<nsIContent> content;
PRInt32 i, count = 0;
nsresult rv = NS_OK;
ChildCount(count);
if (count) {
for (i = count-1; i > 1; i--) {
RemoveChildAt(i, PR_FALSE);
}
rv = ChildAt(0, *getter_AddRefs(content));
NS_ENSURE_SUCCESS(rv, rv);
} else {
rv = NS_NewTextNode(getter_AddRefs(content));
NS_ENSURE_SUCCESS(rv, rv);
rv = InsertChildAt(content, 0, PR_FALSE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
}
if (content) {
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(content));
if (node) {
rv = node->SetNodeValue(aValue);
}
}
return rv;
return ReplaceContentsWithText(aValue, PR_TRUE);
}
NS_IMETHODIMP
@ -351,6 +302,18 @@ NS_IMPL_BOOL_ATTR(nsHTMLScriptElement, Defer, defer)
NS_IMPL_STRING_ATTR(nsHTMLScriptElement, Src, src)
NS_IMPL_STRING_ATTR(nsHTMLScriptElement, Type, type)
NS_IMETHODIMP
nsHTMLScriptElement::GetInnerHTML(nsAString& aInnerHTML)
{
return GetContentsAsText(aInnerHTML);
}
NS_IMETHODIMP
nsHTMLScriptElement::SetInnerHTML(const nsAString& aInnerHTML)
{
return ReplaceContentsWithText(aInnerHTML, PR_TRUE);
}
#ifdef DEBUG
NS_IMETHODIMP

View File

@ -43,6 +43,7 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIAtom.h"
class nsHTMLSpanElement : public nsGenericHTMLContainerElement,
public nsIDOMHTMLElement
@ -63,6 +64,9 @@ public:
// nsIDOMHTMLElement
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLContainerElement::)
NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML);
#ifdef DEBUG
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
#endif
@ -143,6 +147,30 @@ nsHTMLSpanElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSpanElement::GetInnerHTML(nsAString& aInnerHTML)
{
nsCOMPtr<nsIAtom> tag;
GetTag(*getter_AddRefs(tag));
if (tag == nsHTMLAtoms::xmp || tag == nsHTMLAtoms::plaintext) {
return GetContentsAsText(aInnerHTML);
}
return nsGenericHTMLContainerElement::GetInnerHTML(aInnerHTML);
}
NS_IMETHODIMP
nsHTMLSpanElement::SetInnerHTML(const nsAString& aInnerHTML)
{
nsCOMPtr<nsIAtom> tag;
GetTag(*getter_AddRefs(tag));
if (tag == nsHTMLAtoms::xmp || tag == nsHTMLAtoms::plaintext) {
return ReplaceContentsWithText(aInnerHTML, PR_TRUE);
}
return nsGenericHTMLContainerElement::SetInnerHTML(aInnerHTML);
}
#ifdef DEBUG
NS_IMETHODIMP
nsHTMLSpanElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const

View File

@ -164,6 +164,9 @@ public:
return rv;
}
NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML);
#ifdef DEBUG
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
#endif
@ -296,6 +299,25 @@ nsHTMLStyleElement::SetDisabled(PRBool aDisabled)
NS_IMPL_STRING_ATTR(nsHTMLStyleElement, Media, media)
NS_IMPL_STRING_ATTR(nsHTMLStyleElement, Type, type)
NS_IMETHODIMP
nsHTMLStyleElement::GetInnerHTML(nsAString& aInnerHTML)
{
return GetContentsAsText(aInnerHTML);
}
NS_IMETHODIMP
nsHTMLStyleElement::SetInnerHTML(const nsAString& aInnerHTML)
{
SetEnableUpdates(PR_FALSE);
nsresult rv = ReplaceContentsWithText(aInnerHTML, PR_TRUE);
SetEnableUpdates(PR_TRUE);
UpdateStyleSheet();
return rv;
}
#ifdef DEBUG
NS_IMETHODIMP
nsHTMLStyleElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const

View File

@ -139,6 +139,10 @@ public:
nsEventStatus* aEventStatus);
NS_IMETHOD SetFocus(nsIPresContext* aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext);
NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML);
#ifdef DEBUG
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
#endif
@ -513,73 +517,13 @@ nsHTMLTextAreaElement::SetValueChanged(PRBool aValueChanged)
NS_IMETHODIMP
nsHTMLTextAreaElement::GetDefaultValue(nsAString& aDefaultValue)
{
nsresult rv;
PRInt32 nChildren, i;
nsAutoString defVal;
ChildCount(nChildren);
for (i = 0; i < nChildren; i++) {
nsCOMPtr<nsIContent> child;
nsCOMPtr<nsIDOMText> textNode;
rv = ChildAt(i, *getter_AddRefs(child));
NS_ENSURE_SUCCESS(rv, rv);
textNode = do_QueryInterface(child);
if(textNode) {
nsAutoString tmp;
textNode->GetData(tmp);
defVal.Append(tmp);
}
}
aDefaultValue.Assign(defVal);
return NS_OK;
return GetContentsAsText(aDefaultValue);
}
NS_IMETHODIMP
nsHTMLTextAreaElement::SetDefaultValue(const nsAString& aDefaultValue)
{
nsresult rv;
PRInt32 nChildren, i;
PRBool firstChildUsed = PR_FALSE;
ChildCount(nChildren);
// If a child exist we try to reuse it
if (nChildren > 0) {
nsCOMPtr<nsIContent> child;
nsCOMPtr<nsIDOMText> textNode;
rv = ChildAt(0, *getter_AddRefs(child));
NS_ENSURE_SUCCESS(rv, rv);
textNode = do_QueryInterface(child);
if(textNode) {
rv = textNode->SetData(aDefaultValue);
NS_ENSURE_SUCCESS(rv, rv);
firstChildUsed = PR_TRUE;
}
}
PRInt32 lastChild = firstChildUsed ? 1 : 0;
for (i = nChildren-1; i >= lastChild; i--) {
RemoveChildAt(i, PR_TRUE);
}
if (!firstChildUsed) {
nsCOMPtr<nsIContent> textContent;
rv = NS_NewTextNode(getter_AddRefs(textContent));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMText> textNode;
textNode = do_QueryInterface(textContent);
rv = textNode->SetData(aDefaultValue);
NS_ENSURE_SUCCESS(rv, rv);
AppendChildTo(textContent, PR_TRUE, PR_TRUE);
}
return NS_OK;
return ReplaceContentsWithText(aDefaultValue, PR_TRUE);
}
NS_IMETHODIMP
@ -832,6 +776,19 @@ nsHTMLTextAreaElement::GetType(PRInt32* aType)
}
}
NS_IMETHODIMP
nsHTMLTextAreaElement::GetInnerHTML(nsAString& aInnerHTML)
{
return GetContentsAsText(aInnerHTML);
}
NS_IMETHODIMP
nsHTMLTextAreaElement::SetInnerHTML(const nsAString& aInnerHTML)
{
return ReplaceContentsWithText(aInnerHTML, PR_TRUE);
}
#ifdef DEBUG
NS_IMETHODIMP
nsHTMLTextAreaElement::SizeOf(nsISizeOfHandler* aSizer,

View File

@ -229,6 +229,7 @@ HTML_ATOM(p, "p")
HTML_ATOM(pagex, "pagex")
HTML_ATOM(pagey, "pagey")
HTML_ATOM(param, "param")
HTML_ATOM(plaintext, "plaintext")
HTML_ATOM(pointSize, "point-size")
HTML_ATOM(pre, "pre")
HTML_ATOM(profile, "profile")
@ -308,6 +309,7 @@ HTML_ATOM(wbr, "wbr")
HTML_ATOM(width, "width")
HTML_ATOM(wrap, "wrap")
HTML_ATOM(wrappedFramePseudo, ":-moz-wrapped-frame")
HTML_ATOM(xmp, "xmp")
HTML_ATOM(zindex, "zindex")
HTML_ATOM(z_index, "z-index")