as an Netscape internal XML application. It is designed to allow conversion from our content model to any output format -- most importantly to HTML 3.2 and HTML4.0 format. git-svn-id: svn://10.0.0.236/trunk@5521 18797224-902f-48f8-a5cc-f745e15eee43
669 lines
15 KiB
C++
669 lines
15 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
#include "nsHTMLContent.h"
|
|
#include "nsString.h"
|
|
#include "nsIArena.h"
|
|
#include "nsIAtom.h"
|
|
#include "nsIHTMLAttributes.h"
|
|
#include "nsIContentDelegate.h"
|
|
#include "nsFrame.h"
|
|
#include "nsHTMLIIDs.h"
|
|
#include "nsISupportsArray.h"
|
|
#include "nsCRT.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsIEventListenerManager.h"
|
|
#include "nsEventListenerManager.h"
|
|
#include "nsISizeOfHandler.h"
|
|
|
|
static NS_DEFINE_IID(kIContentDelegateIID, NS_ICONTENTDELEGATE_IID);
|
|
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
|
|
static NS_DEFINE_IID(kIHTMLContent, NS_IHTMLCONTENT_IID);
|
|
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
|
static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID);
|
|
static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
|
|
|
|
static nsIContentDelegate* gContentDelegate;
|
|
|
|
/**
|
|
* THE html content delegate. There is exactly one instance of this
|
|
* class and it's used for all html content. It just turns around
|
|
* and asks the content object to create the frame.
|
|
*/
|
|
class ContentDelegate : public nsIContentDelegate {
|
|
public:
|
|
ContentDelegate();
|
|
NS_DECL_ISUPPORTS
|
|
NS_IMETHOD CreateFrame(nsIPresContext* aPresContext,
|
|
nsIContent* aContent,
|
|
nsIFrame* aParentFrame,
|
|
nsIStyleContext* aStyleContext,
|
|
nsIFrame*& aResult);
|
|
protected:
|
|
~ContentDelegate();
|
|
};
|
|
|
|
ContentDelegate::ContentDelegate()
|
|
{
|
|
NS_INIT_REFCNT();
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(ContentDelegate, kIContentDelegateIID);
|
|
|
|
ContentDelegate::~ContentDelegate()
|
|
{
|
|
}
|
|
|
|
NS_METHOD
|
|
ContentDelegate::CreateFrame(nsIPresContext* aPresContext,
|
|
nsIContent* aContent,
|
|
nsIFrame* aParentFrame,
|
|
nsIStyleContext* aStyleContext,
|
|
nsIFrame*& aResult)
|
|
{
|
|
NS_PRECONDITION(nsnull != aContent, "null ptr");
|
|
|
|
// Make sure the content is html content
|
|
nsIHTMLContent* hc;
|
|
nsIFrame* frame = nsnull;
|
|
nsresult rv = aContent->QueryInterface(kIHTMLContentIID, (void**) &hc);
|
|
if (NS_OK != rv) {
|
|
// This means that *somehow* somebody which is not an html
|
|
// content object got ahold of this delegate and tried to
|
|
// create a frame with it. Give them back an nsFrame.
|
|
rv = nsFrame::NewFrame(&frame, aContent, aParentFrame);
|
|
if (NS_OK == rv) {
|
|
frame->SetStyleContext(aPresContext, aStyleContext);
|
|
}
|
|
}
|
|
else {
|
|
// Ask the content object to create the frame
|
|
rv = hc->CreateFrame(aPresContext, aParentFrame, aStyleContext, frame);
|
|
NS_RELEASE(hc);
|
|
}
|
|
aResult = frame;
|
|
return rv;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void* nsHTMLContent::operator new(size_t size)
|
|
{
|
|
nsHTMLContent* rv = (nsHTMLContent*) ::operator new(size);
|
|
nsCRT::zero(rv, size);
|
|
rv->mInHeap = 1;
|
|
return (void*) rv;
|
|
}
|
|
|
|
void* nsHTMLContent::operator new(size_t size, nsIArena* aArena)
|
|
{
|
|
nsHTMLContent* rv = (nsHTMLContent*) aArena->Alloc(PRInt32(size));
|
|
nsCRT::zero(rv, size);
|
|
return (void*) rv;
|
|
}
|
|
|
|
void nsHTMLContent::operator delete(void* ptr)
|
|
{
|
|
NS_PRECONDITION(nsnull != ptr, "null ptr");
|
|
nsHTMLContent* hc = (nsHTMLContent*) ptr;
|
|
if (nsnull != hc) {
|
|
if (hc->mInHeap) {
|
|
::delete ptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
nsHTMLContent::nsHTMLContent()
|
|
{
|
|
// Create shared content delegate if this is the first html content
|
|
// object being created.
|
|
if (nsnull == gContentDelegate) {
|
|
gContentDelegate = new ContentDelegate();
|
|
}
|
|
|
|
mListenerManager = nsnull;
|
|
|
|
// Add a reference to the shared content delegate object
|
|
NS_ADDREF(gContentDelegate);
|
|
}
|
|
|
|
nsHTMLContent::~nsHTMLContent()
|
|
{
|
|
NS_PRECONDITION(nsnull != gContentDelegate, "null content delegate");
|
|
if (nsnull != gContentDelegate) {
|
|
// Remove our reference to the shared content delegate object. If
|
|
// the last reference just went away, null out gContentDelegate.
|
|
nsrefcnt rc = gContentDelegate->Release();
|
|
if (0 == rc) {
|
|
gContentDelegate = nsnull;
|
|
}
|
|
}
|
|
}
|
|
|
|
NS_IMPL_ADDREF(nsHTMLContent)
|
|
NS_IMPL_RELEASE(nsHTMLContent)
|
|
|
|
nsresult nsHTMLContent::QueryInterface(const nsIID& aIID,
|
|
void** aInstancePtrResult)
|
|
{
|
|
NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
|
|
if (nsnull == aInstancePtrResult) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
if (aIID.Equals(kIHTMLContentIID)) {
|
|
*aInstancePtrResult = (void*) ((nsIHTMLContent*)this);
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(kIContentIID)) {
|
|
*aInstancePtrResult = (void*) ((nsIContent*)this);
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(kISupportsIID)) {
|
|
*aInstancePtrResult = (void*)(nsISupports*)(nsIContent*)this;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(kIDOMNodeIID)) {
|
|
*aInstancePtrResult = (void*)(nsIDOMNode*)this;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(kIScriptObjectOwnerIID)) {
|
|
*aInstancePtrResult = (void*)(nsIScriptObjectOwner*)this;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(kIDOMEventReceiverIID)) {
|
|
*aInstancePtrResult = (void*)(nsIDOMEventReceiver*)this;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
return NS_NOINTERFACE;
|
|
}
|
|
|
|
NS_METHOD
|
|
nsHTMLContent::IsSynthetic(PRBool& aResult)
|
|
{
|
|
aResult = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
void nsHTMLContent::Compact()
|
|
{
|
|
}
|
|
|
|
nsresult
|
|
nsHTMLContent::GetDocument(nsIDocument*& aResult) const
|
|
{
|
|
aResult = mDocument;
|
|
NS_IF_ADDREF(mDocument);
|
|
return NS_OK;
|
|
}
|
|
|
|
void nsHTMLContent::SetDocument(nsIDocument* aDocument)
|
|
{
|
|
mDocument = aDocument;
|
|
}
|
|
|
|
nsIContent* nsHTMLContent::GetParent() const
|
|
{
|
|
NS_IF_ADDREF(mParent);
|
|
return mParent;
|
|
}
|
|
|
|
void nsHTMLContent::SetParent(nsIContent* aParent)
|
|
{
|
|
mParent = aParent;
|
|
}
|
|
|
|
PRBool nsHTMLContent::CanContainChildren() const
|
|
{
|
|
return PR_FALSE;
|
|
}
|
|
|
|
PRInt32 nsHTMLContent::ChildCount() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
nsIContent* nsHTMLContent::ChildAt(PRInt32 aIndex) const
|
|
{
|
|
return nsnull;
|
|
}
|
|
|
|
PRInt32 nsHTMLContent::IndexOf(nsIContent* aPossibleChild) const
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::AppendChild(nsIContent* aKid, PRBool aNotify)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
void nsHTMLContent::SetAttribute(const nsString& aName, const nsString& aValue)
|
|
{
|
|
}
|
|
|
|
nsContentAttr nsHTMLContent::GetAttribute(const nsString& aName,
|
|
nsString& aResult) const
|
|
{
|
|
aResult.SetLength(0);
|
|
return eContentAttr_NotThere;
|
|
}
|
|
|
|
void nsHTMLContent::SetAttribute(nsIAtom* aAttribute, const nsString& aValue)
|
|
{
|
|
}
|
|
|
|
void nsHTMLContent::SetAttribute(nsIAtom* aAttribute, const nsHTMLValue& aValue)
|
|
{
|
|
}
|
|
|
|
void nsHTMLContent::UnsetAttribute(nsIAtom* aAttribute)
|
|
{
|
|
}
|
|
|
|
nsContentAttr nsHTMLContent::GetAttribute(nsIAtom* aAttribute,
|
|
nsHTMLValue& aValue) const
|
|
{
|
|
aValue.Reset();
|
|
return eContentAttr_NotThere;
|
|
}
|
|
|
|
PRInt32 nsHTMLContent::GetAllAttributeNames(nsISupportsArray* aArray) const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
PRInt32 nsHTMLContent::GetAttributeCount(void) const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void nsHTMLContent::SetID(nsIAtom* aID)
|
|
{
|
|
}
|
|
|
|
nsIAtom* nsHTMLContent::GetID(void) const
|
|
{
|
|
return nsnull;
|
|
}
|
|
|
|
void nsHTMLContent::SetClass(nsIAtom* aClass)
|
|
{
|
|
}
|
|
|
|
nsIAtom* nsHTMLContent::GetClass(void) const
|
|
{
|
|
return nsnull;
|
|
}
|
|
|
|
nsIStyleRule* nsHTMLContent::GetStyleRule(void)
|
|
{
|
|
return nsnull;
|
|
}
|
|
|
|
void nsHTMLContent::MapAttributesInto(nsIStyleContext* aContext,
|
|
nsIPresContext* aPresContext)
|
|
{
|
|
}
|
|
|
|
|
|
void nsHTMLContent::ListAttributes(FILE* out) const
|
|
{
|
|
nsISupportsArray* attrs;
|
|
if (NS_OK == NS_NewISupportsArray(&attrs)) {
|
|
GetAllAttributeNames(attrs);
|
|
PRInt32 count = attrs->Count();
|
|
PRInt32 index;
|
|
for (index = 0; index < count; index++) {
|
|
// name
|
|
nsIAtom* attr = (nsIAtom*)attrs->ElementAt(index);
|
|
nsAutoString buffer;
|
|
attr->ToString(buffer);
|
|
|
|
// value
|
|
nsAutoString value;
|
|
GetAttribute(buffer, value);
|
|
buffer.Append("=");
|
|
buffer.Append(value);
|
|
|
|
fputs(" ", out);
|
|
fputs(buffer, out);
|
|
NS_RELEASE(attr);
|
|
}
|
|
NS_RELEASE(attrs);
|
|
}
|
|
}
|
|
|
|
void nsHTMLContent::List(FILE* out, PRInt32 aIndent) const
|
|
{
|
|
NS_PRECONDITION(nsnull != mDocument, "bad content");
|
|
|
|
PRInt32 index;
|
|
for (index = aIndent; --index >= 0; ) fputs(" ", out);
|
|
|
|
nsIAtom* tag = GetTag();
|
|
if (tag != nsnull) {
|
|
nsAutoString buf;
|
|
tag->ToString(buf);
|
|
fputs(buf, out);
|
|
NS_RELEASE(tag);
|
|
}
|
|
|
|
ListAttributes(out);
|
|
|
|
fprintf(out, " RefCount=%d<\n", mRefCnt);
|
|
|
|
if (CanContainChildren()) {
|
|
PRInt32 kids = ChildCount();
|
|
for (index = 0; index < kids; index++) {
|
|
nsIContent* kid = ChildAt(index);
|
|
kid->List(out, aIndent + 1);
|
|
NS_RELEASE(kid);
|
|
}
|
|
}
|
|
|
|
for (index = aIndent; --index >= 0; ) fputs(" ", out);
|
|
fputs(">\n", out);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::SizeOf(nsISizeOfHandler* aHandler) const
|
|
{
|
|
aHandler->Add(sizeof(*this));
|
|
nsHTMLContent::SizeOfWithoutThis(aHandler);
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
nsHTMLContent::SizeOfWithoutThis(nsISizeOfHandler* aHandler) const
|
|
{
|
|
// XXX mScriptObject
|
|
}
|
|
|
|
nsIAtom* nsHTMLContent::GetTag() const
|
|
{
|
|
return nsnull;
|
|
}
|
|
|
|
void nsHTMLContent::ToHTML(FILE* out) const
|
|
{
|
|
nsAutoString tmp;
|
|
ToHTMLString(tmp);
|
|
fputs(tmp, out);
|
|
}
|
|
|
|
nsIContentDelegate* nsHTMLContent::GetDelegate(nsIPresContext* aCX)
|
|
{
|
|
gContentDelegate->AddRef();
|
|
return gContentDelegate;
|
|
}
|
|
|
|
void nsHTMLContent::NewGlobalAtom(const char* aString, nsIAtom** aAtomResult)
|
|
{
|
|
if (nsnull == *aAtomResult) {
|
|
*aAtomResult = NS_NewAtom(aString);
|
|
} else {
|
|
NS_ADDREF(*aAtomResult);
|
|
}
|
|
}
|
|
|
|
void nsHTMLContent::ReleaseGlobalAtom(nsIAtom** aAtomResult)
|
|
{
|
|
nsIAtom* atom = *aAtomResult;
|
|
if (nsnull != atom) {
|
|
if (0 == atom->Release()) {
|
|
*aAtomResult = nsnull;
|
|
}
|
|
}
|
|
}
|
|
|
|
nsresult nsHTMLContent::ResetScriptObject()
|
|
{
|
|
mScriptObject = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
//
|
|
// Implementation of nsIDOMNode interface
|
|
//
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::GetParentNode(nsIDOMNode** aParentNode)
|
|
{
|
|
if (nsnull != mParent) {
|
|
nsresult res = mParent->QueryInterface(kIDOMNodeIID, (void**)aParentNode);
|
|
NS_ASSERTION(NS_OK == res, "Must be a DOM Node");
|
|
return res;
|
|
}
|
|
else {
|
|
*aParentNode = nsnull;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::GetChildNodes(nsIDOMNodeList** aChildNodes)
|
|
{
|
|
*aChildNodes = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::GetHasChildNodes(PRBool* aHasChildNodes)
|
|
{
|
|
*aHasChildNodes = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::GetFirstChild(nsIDOMNode** aFirstChild)
|
|
{
|
|
*aFirstChild = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::GetLastChild(nsIDOMNode** aLastChild)
|
|
{
|
|
*aLastChild = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::GetPreviousSibling(nsIDOMNode** aNode)
|
|
{
|
|
if (nsnull != mParent) {
|
|
PRInt32 pos = mParent->IndexOf(this);
|
|
if (pos > -1) {
|
|
nsIContent* prev = mParent->ChildAt(--pos);
|
|
if (nsnull != prev) {
|
|
nsresult res = prev->QueryInterface(kIDOMNodeIID, (void**)aNode);
|
|
NS_ASSERTION(NS_OK == res, "Must be a DOM Node");
|
|
|
|
NS_RELEASE(prev); // balance the AddRef in ChildAt()
|
|
|
|
return res;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::GetNextSibling(nsIDOMNode** aNextSibling)
|
|
{
|
|
if (nsnull != mParent) {
|
|
PRInt32 pos = mParent->IndexOf(this);
|
|
if (pos > -1 ) {
|
|
nsIContent* prev = mParent->ChildAt(++pos);
|
|
if (nsnull != prev) {
|
|
nsresult res = prev->QueryInterface(kIDOMNodeIID, (void**)aNextSibling);
|
|
NS_ASSERTION(NS_OK == res, "Must be a DOM Node");
|
|
NS_RELEASE(prev); // balance the AddRef in ChildAt()
|
|
|
|
return res;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
|
|
{
|
|
aAttributes = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLContent::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsresult nsHTMLContent::GetListenerManager(nsIEventListenerManager **aInstancePtrResult)
|
|
{
|
|
if (nsnull != mListenerManager) {
|
|
return mListenerManager->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult);;
|
|
}
|
|
else {
|
|
nsIEventListenerManager* l = new nsEventListenerManager();
|
|
|
|
if (nsnull == l) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
|
|
if (NS_OK == l->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult)) {
|
|
mListenerManager = l;
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
}
|
|
|
|
nsresult nsHTMLContent::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
|
|
{
|
|
nsIEventListenerManager *manager;
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
manager->AddEventListener(aListener, aIID);
|
|
return NS_OK;
|
|
}
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsresult nsHTMLContent::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
|
|
{
|
|
nsIEventListenerManager *manager;
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
manager->RemoveEventListener(aListener, aIID);
|
|
return NS_OK;
|
|
}
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsresult nsHTMLContent::HandleDOMEvent(nsIPresContext& aPresContext,
|
|
nsGUIEvent* aEvent,
|
|
nsIDOMEvent* aDOMEvent,
|
|
nsEventStatus& aEventStatus)
|
|
{
|
|
//Capturing stage
|
|
|
|
//Local handling stage
|
|
if (nsnull != mListenerManager) {
|
|
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
|
|
}
|
|
|
|
//Bubbling stage
|
|
if (mParent != nsnull) {
|
|
return mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
// XXX i18n: this is wrong (?) because we need to know the outgoing
|
|
// character set (I think)
|
|
void
|
|
nsHTMLContent::QuoteForHTML(const nsString& aValue, nsString& aResult)
|
|
{
|
|
aResult.Truncate();
|
|
const PRUnichar* cp = aValue.GetUnicode();
|
|
const PRUnichar* end = aValue.GetUnicode() + aValue.Length();
|
|
aResult.Append('"');
|
|
while (cp < end) {
|
|
PRUnichar ch = *cp++;
|
|
if ((ch >= 0x20) && (ch <= 0x7f)) {
|
|
if (ch == '\"') {
|
|
aResult.Append(""");
|
|
}
|
|
else {
|
|
aResult.Append(ch);
|
|
}
|
|
}
|
|
else {
|
|
aResult.Append("&#");
|
|
aResult.Append((PRInt32) ch, 10);
|
|
aResult.Append(';');
|
|
}
|
|
}
|
|
aResult.Append('"');
|
|
}
|