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:
parent
f29a33f656
commit
5483f8d08e
@ -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()
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
@ -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")
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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")
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user