Back to index

lightning-sunbird  0.9+nobinonly
Classes | Public Member Functions | Protected Member Functions | Protected Attributes
nsHTMLContentSerializer Class Reference

#include <nsHTMLContentSerializer.h>

Inheritance diagram for nsHTMLContentSerializer:
Inheritance graph
[legend]
Collaboration diagram for nsHTMLContentSerializer:
Collaboration graph
[legend]

List of all members.

Classes

struct  olState

Public Member Functions

 nsHTMLContentSerializer ()
virtual ~nsHTMLContentSerializer ()
NS_IMETHOD Init (PRUint32 flags, PRUint32 aWrapColumn, const char *aCharSet, PRBool aIsCopying)
NS_IMETHOD AppendText (nsIDOMText *aText, PRInt32 aStartOffset, PRInt32 aEndOffset, nsAString &aStr)
NS_IMETHOD AppendElementStart (nsIDOMElement *aElement, PRBool aHasChildren, nsAString &aStr)
NS_IMETHOD AppendElementEnd (nsIDOMElement *aElement, nsAString &aStr)
NS_IMETHOD AppendDocumentStart (nsIDOMDocument *aDocument, nsAString &aStr)
 Append any items in the beginning of the document that won't be serialized by other methods.
NS_IMETHOD AppendCDATASection (nsIDOMCDATASection *aCDATASection, PRInt32 aStartOffset, PRInt32 aEndOffset, nsAString &aStr)
NS_IMETHOD AppendProcessingInstruction (nsIDOMProcessingInstruction *aPI, PRInt32 aStartOffset, PRInt32 aEndOffset, nsAString &aStr)
NS_IMETHOD AppendComment (nsIDOMComment *aComment, PRInt32 aStartOffset, PRInt32 aEndOffset, nsAString &aStr)
NS_IMETHOD AppendDoctype (nsIDOMDocumentType *aDoctype, nsAString &aStr)
NS_IMETHOD Flush (nsAString &aStr)

Protected Member Functions

PRBool LineBreakBeforeOpen (nsIAtom *aName, PRBool aHasDirtyAttr)
PRBool LineBreakAfterOpen (nsIAtom *aName, PRBool aHasDirtyAttr)
PRBool LineBreakBeforeClose (nsIAtom *aName, PRBool aHasDirtyAttr)
PRBool LineBreakAfterClose (nsIAtom *aName, PRBool aHasDirtyAttr)
PRBool IsFirstChildOfOL (nsIDOMElement *aElement)
void StartIndentation (nsIAtom *aName, PRBool aHasDirtyAttr, nsAString &aStr)
void EndIndentation (nsIAtom *aName, PRBool aHasDirtyAttr, nsAString &aStr)
nsresult GetEntityConverter (nsIEntityConverter **aConverter)
void SerializeAttributes (nsIContent *aContent, nsIAtom *aTagName, nsAString &aStr)
void SerializeLIValueAttribute (nsIDOMElement *aElement, nsAString &aStr)
virtual void AppendToString (const PRUnichar *aStr, PRInt32 aLength, nsAString &aOutputStr)
virtual void AppendToString (const PRUnichar aChar, nsAString &aOutputStr)
virtual void AppendToString (const nsAString &aStr, nsAString &aOutputStr, PRBool aTranslateEntities=PR_FALSE, PRBool aIncrColumn=PR_TRUE)
virtual void AppendToStringConvertLF (const nsAString &aStr, nsAString &aOutputStr)
void AppendWrapped_WhitespaceSequence (nsASingleFragmentString::const_char_iterator &aPos, const nsASingleFragmentString::const_char_iterator aEnd, const nsASingleFragmentString::const_char_iterator aSequenceStart, PRBool &aMayIgnoreStartOfLineWhitespaceSequence, nsAString &aOutputStr)
void AppendWrapped_NonWhitespaceSequence (nsASingleFragmentString::const_char_iterator &aPos, const nsASingleFragmentString::const_char_iterator aEnd, const nsASingleFragmentString::const_char_iterator aSequenceStart, PRBool &aMayIgnoreStartOfLineWhitespaceSequence, nsAString &aOutputStr)
virtual void AppendToStringWrapped (const nsASingleFragmentString &aStr, nsAString &aOutputStr, PRBool aTranslateEntities)
PRBool HasLongLines (const nsString &text, PRInt32 &aLastNewlineOffset)
nsresult EscapeURI (const nsAString &aURI, nsAString &aEscapedURI)
PRBool IsJavaScript (nsIAtom *aAttrNameAtom, const nsAString &aAttrValueString)
nsresult AppendTextData (nsIDOMNode *aNode, PRInt32 aStartOffset, PRInt32 aEndOffset, nsAString &aStr, PRBool aTranslateEntities, PRBool aIncrColumn)
virtual nsresult PushNameSpaceDecl (const nsAString &aPrefix, const nsAString &aURI, nsIDOMElement *aOwner)
void PopNameSpaceDeclsFor (nsIDOMElement *aOwner)
PRBool ConfirmPrefix (nsAString &aPrefix, const nsAString &aURI, nsIDOMElement *aElement, PRBool aMustHavePrefix)
 The problem that ConfirmPrefix fixes is that anyone can insert nodes through the DOM that have a namespace URI and a random or empty or previously existing prefix that's totally unrelated to the prefixes declared at that point through xmlns attributes.
void GenerateNewPrefix (nsAString &aPrefix)
 GenerateNewPrefix generates a new prefix and writes it to aPrefix.
void SerializeAttr (const nsAString &aPrefix, const nsAString &aName, const nsAString &aValue, nsAString &aStr, PRBool aDoEscapeEntities)
PRBool IsShorthandAttr (const nsIAtom *aAttrName, const nsIAtom *aElementName)
void MaybeAddNewline (nsAString &aStr)
void MaybeFlagNewline (nsIDOMNode *aNode)

Protected Attributes

nsCOMPtr< nsIEntityConvertermEntityConverter
PRInt32 mIndent
PRInt32 mColPos
PRUint32 mFlags
PRPackedBool mInBody
PRPackedBool mDoFormat
PRPackedBool mDoHeader
PRPackedBool mBodyOnly
PRPackedBool mIsCopying
PRPackedBool mAddSpace
PRPackedBool mMayIgnoreLineBreakSequence
PRPackedBool mIsFirstChildOfOL
PRInt32 mPreLevel
PRPackedBool mInCDATA
PRPackedBool mNeedLineBreaker
nsCOMPtr< nsILineBreakermLineBreaker
PRInt32 mMaxColumn
nsString mLineBreak
nsCString mCharSet
nsAutoVoidArray mOLStateStack
PRInt32 mPrefixIndex
nsVoidArray mNameSpaceStack
PRPackedBool mInAttribute
PRPackedBool mAddNewline

Detailed Description

Definition at line 49 of file nsHTMLContentSerializer.h.


Constructor & Destructor Documentation

Definition at line 94 of file nsHTMLContentSerializer.cpp.

{
  NS_ASSERTION(mOLStateStack.Count() == 0, "Expected OL State stack to be empty");
  if (mOLStateStack.Count() > 0){
    for (PRInt32 i = 0; i < mOLStateStack.Count(); i++){
      olState* state = (olState*)mOLStateStack[i];
      delete state;
      mOLStateStack.RemoveElementAt(i);
    }
  }
}

Member Function Documentation

NS_IMETHODIMP nsXMLContentSerializer::AppendCDATASection ( nsIDOMCDATASection aCDATASection,
PRInt32  aStartOffset,
PRInt32  aEndOffset,
nsAString &  aStr 
) [virtual, inherited]

Implements nsIContentSerializer.

Definition at line 147 of file nsXMLContentSerializer.cpp.

{
  NS_ENSURE_ARG(aCDATASection);
  nsresult rv;

  AppendToString(NS_LITERAL_STRING("<![CDATA["), aStr);
  rv = AppendTextData(aCDATASection, aStartOffset, aEndOffset, aStr, PR_FALSE, PR_TRUE);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;  
  AppendToString(NS_LITERAL_STRING("]]>"), aStr);

  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsXMLContentSerializer::AppendComment ( nsIDOMComment aComment,
PRInt32  aStartOffset,
PRInt32  aEndOffset,
nsAString &  aStr 
) [virtual, inherited]

Implements nsIContentSerializer.

Definition at line 194 of file nsXMLContentSerializer.cpp.

{
  NS_ENSURE_ARG(aComment);
  nsresult rv;
  nsAutoString data;

  rv = aComment->GetData(data);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

  MaybeAddNewline(aStr);

  AppendToString(NS_LITERAL_STRING("<!--"), aStr);
  if (aStartOffset || (aEndOffset != -1)) {
    PRInt32 length = (aEndOffset == -1) ? data.Length() : aEndOffset;
    length -= aStartOffset;

    nsAutoString frag;
    data.Mid(frag, aStartOffset, length);
    AppendToString(frag, aStr);
  }
  else {
    AppendToString(data, aStr);
  }
  AppendToString(NS_LITERAL_STRING("-->"), aStr);
  MaybeFlagNewline(aComment);
  
  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsXMLContentSerializer::AppendDoctype ( nsIDOMDocumentType aDoctype,
nsAString &  aStr 
) [virtual, inherited]

Implements nsIContentSerializer.

Definition at line 227 of file nsXMLContentSerializer.cpp.

{
  NS_ENSURE_ARG(aDoctype);
  nsresult rv;
  nsAutoString name, publicId, systemId, internalSubset;

  rv = aDoctype->GetName(name);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
  rv = aDoctype->GetPublicId(publicId);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
  rv = aDoctype->GetSystemId(systemId);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
  rv = aDoctype->GetInternalSubset(internalSubset);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

  MaybeAddNewline(aStr);

  AppendToString(NS_LITERAL_STRING("<!DOCTYPE "), aStr);
  AppendToString(name, aStr);
  PRUnichar quote;
  if (!publicId.IsEmpty()) {
    AppendToString(NS_LITERAL_STRING(" PUBLIC "), aStr);
    if (publicId.FindChar(PRUnichar('"')) == -1) {
      quote = PRUnichar('"');
    }
    else {
      quote = PRUnichar('\'');
    }
    AppendToString(quote, aStr);
    AppendToString(publicId, aStr);
    AppendToString(quote, aStr);

    if (!systemId.IsEmpty()) {
      AppendToString(PRUnichar(' '), aStr);
      if (systemId.FindChar(PRUnichar('"')) == -1) {
        quote = PRUnichar('"');
      }
      else {
        quote = PRUnichar('\'');
      }
      AppendToString(quote, aStr);
      AppendToString(systemId, aStr);
      AppendToString(quote, aStr);
    }
  }
  else if (!systemId.IsEmpty()) {
    if (systemId.FindChar(PRUnichar('"')) == -1) {
      quote = PRUnichar('"');
    }
    else {
      quote = PRUnichar('\'');
    }
    AppendToString(NS_LITERAL_STRING(" SYSTEM "), aStr);
    AppendToString(quote, aStr);
    AppendToString(systemId, aStr);
    AppendToString(quote, aStr);
  }
  
  if (!internalSubset.IsEmpty()) {
    AppendToString(NS_LITERAL_STRING(" ["), aStr);
    AppendToString(internalSubset, aStr);
    AppendToString(PRUnichar(']'), aStr);
  }
    
  AppendToString(PRUnichar('>'), aStr);
  MaybeFlagNewline(aDoctype);

  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsHTMLContentSerializer::AppendDocumentStart ( nsIDOMDocument aDocument,
nsAString &  aStr 
) [virtual]

Append any items in the beginning of the document that won't be serialized by other methods.

XML declaration is the most likely thing this method can produce.

Reimplemented from nsXMLContentSerializer.

Definition at line 449 of file nsHTMLContentSerializer.cpp.

{
  return NS_OK;
}
NS_IMETHODIMP nsHTMLContentSerializer::AppendElementEnd ( nsIDOMElement aElement,
nsAString &  aStr 
) [virtual]

Reimplemented from nsXMLContentSerializer.

Definition at line 771 of file nsHTMLContentSerializer.cpp.

{
  NS_ENSURE_ARG(aElement);

  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
  if (!content) return NS_ERROR_FAILURE;

  PRBool hasDirtyAttr = content->HasAttr(kNameSpaceID_None,
                                         nsLayoutAtoms::mozdirty);

  nsIAtom *name = content->Tag();

  if (name == nsHTMLAtoms::pre ||
      name == nsHTMLAtoms::script ||
      name == nsHTMLAtoms::style) {
    mPreLevel--;
  }

  if (mIsCopying && (name == nsHTMLAtoms::ol)){
    NS_ASSERTION((mOLStateStack.Count() > 0), "Cannot have an empty OL Stack");
    /* Though at this point we must always have an state to be deleted as all 
    the OL opening tags are supposed to push an olState object to the stack*/
    if (mOLStateStack.Count() > 0) {
      olState* state = (olState*)mOLStateStack.ElementAt(mOLStateStack.Count() -1);
      mOLStateStack.RemoveElementAt(mOLStateStack.Count() -1);
      delete state;
    }
  }
  
  nsIParserService* parserService = nsContentUtils::GetParserServiceWeakRef();

  if (parserService && (name != nsHTMLAtoms::style)) {
    PRBool isContainer;

    parserService->IsContainer(parserService->HTMLAtomTagToId(name),
                               isContainer);
    if (!isContainer) return NS_OK;
  }

  if (LineBreakBeforeClose(name, hasDirtyAttr)) {
    AppendToString(mLineBreak, aStr);
    mMayIgnoreLineBreakSequence = PR_TRUE;
    mColPos = 0;
    mAddSpace = PR_FALSE;
  }
  else if (mAddSpace) {
    AppendToString(PRUnichar(' '), aStr);
    mAddSpace = PR_FALSE;
  }

  EndIndentation(name, hasDirtyAttr, aStr);

  nsAutoString nameStr;
  name->ToString(nameStr);

  AppendToString(kEndTag, aStr);
  AppendToString(nameStr.get(), -1, aStr);
  AppendToString(kGreaterThan, aStr);

  if (LineBreakAfterClose(name, hasDirtyAttr)) {
    AppendToString(mLineBreak, aStr);
    mMayIgnoreLineBreakSequence = PR_TRUE;
    mColPos = 0;
  }
  else {
    MaybeFlagNewline(aElement);
  }

  mInCDATA = PR_FALSE;

  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsHTMLContentSerializer::AppendElementStart ( nsIDOMElement aElement,
PRBool  aHasChildren,
nsAString &  aStr 
) [virtual]

Reimplemented from nsXMLContentSerializer.

Definition at line 656 of file nsHTMLContentSerializer.cpp.

{
  NS_ENSURE_ARG(aElement);
  
  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
  if (!content) return NS_ERROR_FAILURE;
  
  // The _moz_dirty attribute is emitted by the editor to
  // indicate that this element should be pretty printed
  // even if we're not in pretty printing mode
  PRBool hasDirtyAttr = content->HasAttr(kNameSpaceID_None,
                                         nsLayoutAtoms::mozdirty);

  nsIAtom *name = content->Tag();

  if (name == nsHTMLAtoms::br && mPreLevel > 0
      && (mFlags & nsIDocumentEncoder::OutputNoFormattingInPre)) {
    AppendToString(mLineBreak, aStr);
    mMayIgnoreLineBreakSequence = PR_TRUE;
    mColPos = 0;
    return NS_OK;
  }

  if (name == nsHTMLAtoms::body) {
    mInBody = PR_TRUE;
  }

  if (LineBreakBeforeOpen(name, hasDirtyAttr)) {
    AppendToString(mLineBreak, aStr);
    mMayIgnoreLineBreakSequence = PR_TRUE;
    mColPos = 0;
    mAddSpace = PR_FALSE;
  }
  else if (mAddSpace) {
    AppendToString(PRUnichar(' '), aStr);
    mAddSpace = PR_FALSE;
  }
  else {
    MaybeAddNewline(aStr);
  }
  // Always reset to avoid false newlines in case MaybeAddNewline wasn't
  // called
  mAddNewline = PR_FALSE;

  StartIndentation(name, hasDirtyAttr, aStr);

  if (name == nsHTMLAtoms::pre ||
      name == nsHTMLAtoms::script ||
      name == nsHTMLAtoms::style) {
    mPreLevel++;
  }
  
  AppendToString(kLessThan, aStr);

  nsAutoString nameStr;
  name->ToString(nameStr);
  AppendToString(nameStr.get(), -1, aStr);

  // Need to keep track of OL and LI elements in order to get ordinal number 
  // for the LI.
  if (mIsCopying && name == nsHTMLAtoms::ol){
    // We are copying and current node is an OL;
    // Store it's start attribute value in olState->startVal.
    nsAutoString start;
    PRInt32 startAttrVal = 0;
    aElement->GetAttribute(NS_LITERAL_STRING("start"), start);
    if (!start.IsEmpty()){
      PRInt32 rv = 0;
      startAttrVal = start.ToInteger(&rv);
      //If OL has "start" attribute, first LI element has to start with that value
      //Therefore subtracting 1 as all the LI elements are incrementing it before using it;
      //In failure of ToInteger(), default StartAttrValue to 0.
      if (NS_SUCCEEDED(rv))
        startAttrVal--; 
      else
        startAttrVal = 0;
    }
    olState* state = new olState(startAttrVal, PR_TRUE);
    if (state)
      mOLStateStack.AppendElement(state);
  }

  if (mIsCopying && name == nsHTMLAtoms::li) {
    mIsFirstChildOfOL = IsFirstChildOfOL(aElement);
    if (mIsFirstChildOfOL){
      // If OL is parent of this LI, serialize attributes in different manner.
      SerializeLIValueAttribute(aElement, aStr);
    }
  }

  // Even LI passed above have to go through this 
  // for serializing attributes other than "value".
  SerializeAttributes(content, name, aStr);

  AppendToString(kGreaterThan, aStr);

  if (LineBreakAfterOpen(name, hasDirtyAttr)) {
    AppendToString(mLineBreak, aStr);
    mMayIgnoreLineBreakSequence = PR_TRUE;
    mColPos = 0;
  }

  if (name == nsHTMLAtoms::script ||
      name == nsHTMLAtoms::style ||
      name == nsHTMLAtoms::noscript ||
      name == nsHTMLAtoms::noframes) {
    mInCDATA = PR_TRUE;
  }

  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsXMLContentSerializer::AppendProcessingInstruction ( nsIDOMProcessingInstruction aPI,
PRInt32  aStartOffset,
PRInt32  aEndOffset,
nsAString &  aStr 
) [virtual, inherited]

Implements nsIContentSerializer.

Definition at line 164 of file nsXMLContentSerializer.cpp.

{
  NS_ENSURE_ARG(aPI);
  nsresult rv;
  nsAutoString target, data;

  MaybeAddNewline(aStr);

  rv = aPI->GetTarget(target);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

  rv = aPI->GetData(data);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

  AppendToString(NS_LITERAL_STRING("<?"), aStr);
  AppendToString(target, aStr);
  if (!data.IsEmpty()) {
    AppendToString(NS_LITERAL_STRING(" "), aStr);
    AppendToString(data, aStr);
  }
  AppendToString(NS_LITERAL_STRING("?>"), aStr);
  MaybeFlagNewline(aPI);
  
  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsHTMLContentSerializer::AppendText ( nsIDOMText aText,
PRInt32  aStartOffset,
PRInt32  aEndOffset,
nsAString &  aStr 
) [virtual]

Reimplemented from nsXMLContentSerializer.

Definition at line 152 of file nsHTMLContentSerializer.cpp.

{
  NS_ENSURE_ARG(aText);

  if (mNeedLineBreaker) {
    mNeedLineBreaker = PR_FALSE;

    nsCOMPtr<nsIDOMDocument> domDoc;
    aText->GetOwnerDocument(getter_AddRefs(domDoc));
    nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
    if (document) {
      mLineBreaker = document->GetLineBreaker();
    }

    if (!mLineBreaker) {
      nsresult rv;
      nsCOMPtr<nsILineBreakerFactory> lf(do_GetService(kLWBrkCID, &rv));
      if (NS_SUCCEEDED(rv)) {
        rv = lf->GetBreaker(EmptyString(), getter_AddRefs(mLineBreaker));
        // Ignore result value.
        // If we are unable to obtain a line breaker,
        // we will use our simple fallback logic.
      }
    }
  }

  nsAutoString data;

  nsresult rv;
  rv = AppendTextData((nsIDOMNode*)aText, aStartOffset, 
                      aEndOffset, data, PR_TRUE, PR_FALSE);
  if (NS_FAILED(rv))
    return NS_ERROR_FAILURE;

  if (mPreLevel > 0) {
    AppendToStringConvertLF(data, aStr);
  }
  else if (mFlags & nsIDocumentEncoder::OutputRaw) {
    PRInt32 lastNewlineOffset = data.RFindChar('\n');
    AppendToString(data, aStr);
    if (lastNewlineOffset != kNotFound)
      mColPos = data.Length() - lastNewlineOffset;
  }
  else if (!mDoFormat) {
    PRInt32 lastNewlineOffset = kNotFound;
    PRBool hasLongLines = HasLongLines(data, lastNewlineOffset);
    if (hasLongLines) {
      // We have long lines, rewrap
      AppendToStringWrapped(data, aStr, PR_FALSE);
      if (lastNewlineOffset != kNotFound)
        mColPos = data.Length() - lastNewlineOffset;
    }
    else {
      AppendToStringConvertLF(data, aStr);
    }
  }
  else {
    AppendToStringWrapped(data, aStr, PR_FALSE);
  }

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsXMLContentSerializer::AppendTextData ( nsIDOMNode aNode,
PRInt32  aStartOffset,
PRInt32  aEndOffset,
nsAString &  aStr,
PRBool  aTranslateEntities,
PRBool  aIncrColumn 
) [protected, inherited]

Definition at line 97 of file nsXMLContentSerializer.cpp.

{
  nsCOMPtr<nsITextContent> content(do_QueryInterface(aNode));
  if (!content) return NS_ERROR_FAILURE;

  const nsTextFragment* frag = content->Text();

  PRInt32 endoffset = (aEndOffset == -1) ? frag->GetLength() : aEndOffset;
  PRInt32 length = endoffset - aStartOffset;

  NS_ASSERTION(aStartOffset >= 0, "Negative start offset for text fragment!");
  NS_ASSERTION(aStartOffset <= endoffset, "A start offset is beyond the end of the text fragment!");

  if (length <= 0) {
    // XXX Zero is a legal value, maybe non-zero values should be an
    // error.

    return NS_OK;
  }
    
  if (frag->Is2b()) {
    const PRUnichar *strStart = frag->Get2b() + aStartOffset;
    AppendToString(Substring(strStart, strStart + length), aStr,
                   aTranslateEntities, aIncrColumn);
  }
  else {
    AppendToString(NS_ConvertASCIItoUCS2(frag->Get1b()+aStartOffset, length),
                   aStr, aTranslateEntities, aIncrColumn);
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHTMLContentSerializer::AppendToString ( const PRUnichar aStr,
PRInt32  aLength,
nsAString &  aOutputStr 
) [protected, virtual]

Reimplemented from nsXMLContentSerializer.

Definition at line 846 of file nsHTMLContentSerializer.cpp.

{
  if (mBodyOnly && !mInBody) {
    return;
  }

  PRInt32 length = (aLength == -1) ? nsCRT::strlen(aStr) : aLength;
  
  mColPos += length;

  aOutputStr.Append(aStr, length);
}

Here is the caller graph for this function:

void nsHTMLContentSerializer::AppendToString ( const PRUnichar  aChar,
nsAString &  aOutputStr 
) [protected, virtual]

Reimplemented from nsXMLContentSerializer.

Definition at line 862 of file nsHTMLContentSerializer.cpp.

{
  if (mBodyOnly && !mInBody) {
    return;
  }

  mColPos += 1;

  aOutputStr.Append(aChar);
}
void nsHTMLContentSerializer::AppendToString ( const nsAString &  aStr,
nsAString &  aOutputStr,
PRBool  aTranslateEntities = PR_FALSE,
PRBool  aIncrColumn = PR_TRUE 
) [protected, virtual]

Reimplemented from nsXMLContentSerializer.

Definition at line 899 of file nsHTMLContentSerializer.cpp.

{
  if (mBodyOnly && !mInBody) {
    return;
  }

  if (aIncrColumn) {
    mColPos += aStr.Length();
  }

  if (aTranslateEntities && !mInCDATA) {
    if (mFlags & (nsIDocumentEncoder::OutputEncodeBasicEntities  |
                  nsIDocumentEncoder::OutputEncodeLatin1Entities |
                  nsIDocumentEncoder::OutputEncodeHTMLEntities   |
                  nsIDocumentEncoder::OutputEncodeW3CEntities)) {
      nsIParserService* parserService =
        nsContentUtils::GetParserServiceWeakRef();

      if (!parserService) {
        NS_ERROR("Can't get parser service");
        return;
      }

      nsReadingIterator<PRUnichar> done_reading;
      aStr.EndReading(done_reading);

      // for each chunk of |aString|...
      PRUint32 advanceLength = 0;
      nsReadingIterator<PRUnichar> iter;

      const char **entityTable = mInAttribute ? kAttrEntities : kEntities;

      for (aStr.BeginReading(iter); 
           iter != done_reading; 
           iter.advance(PRInt32(advanceLength))) {
        PRUint32 fragmentLength = iter.size_forward();
        PRUint32 lengthReplaced = 0; // the number of UTF-16 codepoints
                                     //  replaced by a particular entity
        const PRUnichar* c = iter.get();
        const PRUnichar* fragmentStart = c;
        const PRUnichar* fragmentEnd = c + fragmentLength;
        const char* entityText = nsnull;
        nsCAutoString entityReplacement;
        char* fullEntityText = nsnull;

        advanceLength = 0;
        // for each character in this chunk, check if it
        // needs to be replaced
        for (; c < fragmentEnd; c++, advanceLength++) {
          PRUnichar val = *c;
          if (val == kValNBSP) {
            entityText = kEntityNBSP;
            break;
          }
          else if ((val <= kGTVal) && (entityTable[val][0] != 0)) {
            entityText = entityTable[val];
            break;
          } else if (val > 127 &&
                    ((val < 256 &&
                      mFlags & nsIDocumentEncoder::OutputEncodeLatin1Entities) ||
                      mFlags & nsIDocumentEncoder::OutputEncodeHTMLEntities)) {
            parserService->HTMLConvertUnicodeToEntity(val, entityReplacement);

            if (!entityReplacement.IsEmpty()) {
              entityText = entityReplacement.get();
              break;
            }
          }
          else if (val > 127 && 
                   mFlags & nsIDocumentEncoder::OutputEncodeW3CEntities &&
                   mEntityConverter) {
            if (IS_HIGH_SURROGATE(val) &&
                c + 1 < fragmentEnd &&
                IS_LOW_SURROGATE(*(c + 1))) {
              PRUint32 valUTF32 = SURROGATE_TO_UCS4(val, *(++c));
              if (NS_SUCCEEDED(mEntityConverter->ConvertUTF32ToEntity(valUTF32,
                               nsIEntityConverter::entityW3C, &fullEntityText))) {
                lengthReplaced = 2;
                break;
              }
              else {
                advanceLength++;
              }
            }
            else if (NS_SUCCEEDED(mEntityConverter->ConvertToEntity(val,
                                  nsIEntityConverter::entityW3C, 
                                  &fullEntityText))) {
              lengthReplaced = 1;
              break;
            }
          }
        }

        aOutputStr.Append(fragmentStart, advanceLength);
        if (entityText) {
          aOutputStr.Append(PRUnichar('&'));
          AppendASCIItoUTF16(entityText, aOutputStr);
          aOutputStr.Append(PRUnichar(';'));
          advanceLength++;
        }
        // if it comes from nsIEntityConverter, it already has '&' and ';'
        else if (fullEntityText) {
          AppendASCIItoUTF16(fullEntityText, aOutputStr);
          nsMemory::Free(fullEntityText);
          advanceLength += lengthReplaced;
        }
      }
    } else {
      nsXMLContentSerializer::AppendToString(aStr, aOutputStr, aTranslateEntities, aIncrColumn);
    }

    return;
  }

  aOutputStr.Append(aStr);
}

Here is the call graph for this function:

void nsHTMLContentSerializer::AppendToStringConvertLF ( const nsAString &  aStr,
nsAString &  aOutputStr 
) [protected, virtual]

Definition at line 1020 of file nsHTMLContentSerializer.cpp.

{
  // Convert line-endings to mLineBreak
  PRUint32 start = 0;
  PRUint32 theLen = aStr.Length();
  while (start < theLen) {
    PRInt32 eol = aStr.FindChar('\n', start);
    if (eol == kNotFound) {
      nsDependentSubstring dataSubstring(aStr, start, theLen - start);
      AppendToString(dataSubstring, aOutputStr);
      start = theLen;
    }
    else {
      nsDependentSubstring dataSubstring(aStr, start, eol - start);
      AppendToString(dataSubstring, aOutputStr);
      AppendToString(mLineBreak, aOutputStr);
      start = eol + 1;
      if (start == theLen)
        mColPos = 0;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHTMLContentSerializer::AppendToStringWrapped ( const nsASingleFragmentString aStr,
nsAString &  aOutputStr,
PRBool  aTranslateEntities 
) [protected, virtual]

Definition at line 419 of file nsHTMLContentSerializer.cpp.

{
  nsASingleFragmentString::const_char_iterator pos, end, sequenceStart;

  aStr.BeginReading(pos);
  aStr.EndReading(end);

  // if the current line already has text on it, such as a tag,
  // leading whitespace is significant

  PRBool mayIgnoreStartOfLineWhitespaceSequence = !mColPos;

  while (pos < end) {
    sequenceStart = pos;

    // if beginning of a whitespace sequence
    if (*pos == ' ' || *pos == '\n' || *pos == '\t') {
      AppendWrapped_WhitespaceSequence(pos, end, sequenceStart, 
        mayIgnoreStartOfLineWhitespaceSequence, aOutputStr);
    }
    else { // any other non-whitespace char
      AppendWrapped_NonWhitespaceSequence(pos, end, sequenceStart, 
        mayIgnoreStartOfLineWhitespaceSequence, aOutputStr);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHTMLContentSerializer::AppendWrapped_NonWhitespaceSequence ( nsASingleFragmentString::const_char_iterator &  aPos,
const nsASingleFragmentString::const_char_iterator  aEnd,
const nsASingleFragmentString::const_char_iterator  aSequenceStart,
PRBool aMayIgnoreStartOfLineWhitespaceSequence,
nsAString &  aOutputStr 
) [protected]

Definition at line 291 of file nsHTMLContentSerializer.cpp.

{
  mMayIgnoreLineBreakSequence = PR_FALSE;
  aMayIgnoreStartOfLineWhitespaceSequence = PR_FALSE;

  // Handle the complete sequence of non-whitespace in this block
  // Iterate until we find the first whitespace char or an aEnd condition
  // Updates "aPos" to point to the first unhandled char.
  // Also updates the aMayIgnoreStartOfLineWhitespaceSequence flag,
  // as well as the other "global" state flags.

  PRBool thisSequenceStartsAtBeginningOfLine = !mColPos;
  PRBool onceAgainBecauseWeAddedBreakInFront;
  PRBool foundWhitespaceInLoop;

  do {
    onceAgainBecauseWeAddedBreakInFront = PR_FALSE;
    foundWhitespaceInLoop = PR_FALSE;

    do {
      if (*aPos == ' ' || *aPos == '\t' || *aPos == '\n') {
        foundWhitespaceInLoop = PR_TRUE;
        break;
      }

      ++aPos;
      ++mColPos;
    } while (mColPos < mMaxColumn && aPos < aEnd);

    if (aPos == aEnd || foundWhitespaceInLoop) {
      // there is enough room for the complete block we found

      if (mAddSpace) {
        aOutputStr.Append(PRUnichar(' '));
        mAddSpace = PR_FALSE;
      }

      aOutputStr.Append(aSequenceStart, aPos - aSequenceStart);
      // We have not yet reached the max column, we will continue to
      // fill the current line in the next outer loop iteration.
    }
    else { // mColPos == mMaxColumn
      if (!thisSequenceStartsAtBeginningOfLine && mAddSpace) {
        // We can avoid to wrap.

        aOutputStr.Append(mLineBreak);
        mAddSpace = PR_FALSE;
        aPos = aSequenceStart;
        mColPos = 0;
        thisSequenceStartsAtBeginningOfLine = PR_TRUE;
        onceAgainBecauseWeAddedBreakInFront = PR_TRUE;
      }
      else {
        // we must wrap

        PRBool foundWrapPosition = PR_FALSE;

        if (mLineBreaker) { // we have a line breaker helper object
          PRUint32 wrapPosition;
          PRBool needMoreText;
          nsresult rv;

          rv = mLineBreaker->Prev(aSequenceStart,
                                  (aEnd - aSequenceStart),
                                  (aPos - aSequenceStart) + 1,
                                  &wrapPosition,
                                  &needMoreText);
          if (NS_SUCCEEDED(rv) && !needMoreText && wrapPosition > 0) {
            foundWrapPosition = PR_TRUE;
          }
          else {
            rv = mLineBreaker->Next(aSequenceStart,
                                    (aEnd - aSequenceStart),
                                    (aPos - aSequenceStart),
                                    &wrapPosition,
                                    &needMoreText);
            if (NS_SUCCEEDED(rv) && !needMoreText && wrapPosition > 0) {
              foundWrapPosition = PR_TRUE;
            }
          }

          if (foundWrapPosition) {
            if (mAddSpace) {
              aOutputStr.Append(PRUnichar(' '));
              mAddSpace = PR_FALSE;
            }

            aOutputStr.Append(aSequenceStart, wrapPosition);
            aOutputStr.Append(mLineBreak);
            aPos = aSequenceStart + wrapPosition;
            mColPos = 0;
            aMayIgnoreStartOfLineWhitespaceSequence = PR_TRUE;
            mMayIgnoreLineBreakSequence = PR_TRUE;
          }
        }

        if (!mLineBreaker || !foundWrapPosition) {
          // try some simple fallback logic
          // go forward up to the next whitespace position,
          // in the worst case this will be all the rest of the data

          do {
            if (*aPos == ' ' || *aPos == '\t' || *aPos == '\n') {
              break;
            }

            ++aPos;
            ++mColPos;
          } while (aPos < aEnd);

          if (mAddSpace) {
            aOutputStr.Append(PRUnichar(' '));
            mAddSpace = PR_FALSE;
          }

          aOutputStr.Append(aSequenceStart, aPos - aSequenceStart);
        }
      }
    }
  } while (onceAgainBecauseWeAddedBreakInFront);
}

Here is the caller graph for this function:

void nsHTMLContentSerializer::AppendWrapped_WhitespaceSequence ( nsASingleFragmentString::const_char_iterator &  aPos,
const nsASingleFragmentString::const_char_iterator  aEnd,
const nsASingleFragmentString::const_char_iterator  aSequenceStart,
PRBool aMayIgnoreStartOfLineWhitespaceSequence,
nsAString &  aOutputStr 
) [protected]

Definition at line 218 of file nsHTMLContentSerializer.cpp.

{
  // Handle the complete sequence of whitespace.
  // Continue to iterate until we find the first non-whitespace char.
  // Updates "aPos" to point to the first unhandled char.
  // Also updates the aMayIgnoreStartOfLineWhitespaceSequence flag,
  // as well as the other "global" state flags.

  PRBool sawBlankOrTab = PR_FALSE;
  PRBool leaveLoop = PR_FALSE;

  do {
    switch (*aPos) {
      case ' ':
      case '\t':
        sawBlankOrTab = PR_TRUE;
        // no break
      case '\n':
        ++aPos;
        // do not increase mColPos,
        // because we will reduce the whitespace to a single char
        break;
      default:
        leaveLoop = PR_TRUE;
        break;
    }
  } while (!leaveLoop && aPos < aEnd);

  if (mAddSpace) {
    // if we had previously been asked to add space,
    // our situation has not changed
  }
  else if (!sawBlankOrTab && mMayIgnoreLineBreakSequence) {
    // nothing to do
    mMayIgnoreLineBreakSequence = PR_FALSE;
  }
  else if (aMayIgnoreStartOfLineWhitespaceSequence) {
    // nothing to do
    aMayIgnoreStartOfLineWhitespaceSequence = PR_FALSE;
  }
  else {
    if (sawBlankOrTab) {
      if (mColPos + 1 >= mMaxColumn) {
        // no much sense in delaying, we only have one slot left,
        // let's write a break now
        aOutputStr.Append(mLineBreak);
        mColPos = 0;
      }
      else {
        // do not write out yet, we may write out either a space or a linebreak
        // let's delay writing it out until we know more

        mAddSpace = PR_TRUE;
        ++mColPos; // eat a slot of available space
      }
    }
    else {
      // Asian text usually does not contain spaces, therefore we should not
      // transform a linebreak into a space.
      // Since we only saw linebreaks, but no spaces or tabs,
      // let's write a linebreak now.
      aOutputStr.Append(mLineBreak);
      mMayIgnoreLineBreakSequence = PR_TRUE;
      mColPos = 0;
    }
  }
}

Here is the caller graph for this function:

PRBool nsXMLContentSerializer::ConfirmPrefix ( nsAString &  aPrefix,
const nsAString &  aURI,
nsIDOMElement aElement,
PRBool  aMustHavePrefix 
) [protected, inherited]

The problem that ConfirmPrefix fixes is that anyone can insert nodes through the DOM that have a namespace URI and a random or empty or previously existing prefix that's totally unrelated to the prefixes declared at that point through xmlns attributes.

So what ConfirmPrefix does is ensure that we can map aPrefix to the namespace URI aURI (for example, that the prefix is not already mapped to some other namespace). aPrefix will be adjusted, if necessary, so the value of the prefix after this call is what should be serialized.

Parameters:
aPrefixthe prefix that may need adjusting
aURIthe namespace URI we want aPrefix to point to
aElementthe element we're working with (needed for proper default namespace handling)
aMustHavePrefixPR_TRUE if we the output prefix must be nonempty whenever a new namespace decl is needed.
Returns:
PR_TRUE if we need to push the (prefix, uri) pair on the namespace stack (note that this can happen even if the prefix is empty).

Definition at line 335 of file nsXMLContentSerializer.cpp.

{
  if (aPrefix.EqualsLiteral(kXMLNS) ||
      (aPrefix.EqualsLiteral("xml") &&
       aURI.EqualsLiteral("http://www.w3.org/XML/1998/namespace"))) {
    return PR_FALSE;
  }
  if (aURI.IsEmpty()) {
    aPrefix.Truncate();
    return PR_FALSE;
  }

  nsAutoString closestURIMatch;
  PRBool uriMatch = PR_FALSE;

  PRInt32 count = mNameSpaceStack.Count();
  PRInt32 index = count - 1;
  while (index >= 0) {
    NameSpaceDecl* decl = (NameSpaceDecl*)mNameSpaceStack.ElementAt(index);
    // Check if we've found a prefix match
    if (aPrefix.Equals(decl->mPrefix)) {
      
      // If the URI's match, we don't have to add a namespace decl
      if (aURI.Equals(decl->mURI)) {
        return PR_FALSE;
      }

      // If they don't, and either:
      // 1) We have a prefix (so we'd be redeclaring this prefix to point to a
      //    different namespace) or
      // 2) We're looking at an existing default namespace decl on aElement (so
      //    we can't create a new default namespace decl for this URI)
      // then generate a new prefix.  Note that we do NOT generate new prefixes
      // if we happen to have aPrefix == decl->mPrefix == "" and mismatching
      // URIs when |decl| doesn't have aElement as its owner.  In that case we
      // can simply push the new namespace URI as the default namespace for
      // aElement.
      if (!aPrefix.IsEmpty() ||
          (decl->mPrefix.IsEmpty() && decl->mOwner == aElement)) {
        GenerateNewPrefix(aPrefix);
        // Now we need to validate our new prefix/uri combination; check it
        // against the full namespace stack again.  Note that just restarting
        // the while loop is ok, since we haven't changed aURI, so the
        // closestURIMatch state is not affected.
        index = count - 1;
        continue;
      }
    }
    
    // If we've found a URI match, then record the first one
    if (!uriMatch && aURI.Equals(decl->mURI)) {
      // Need to check that decl->mPrefix is not declared anywhere closer to
      // us.  If it is, we can't use it.
      PRBool prefixOK = PR_TRUE;
      PRInt32 index2;
      for (index2 = count-1; index2 > index && prefixOK; --index2) {
        NameSpaceDecl* decl2 =
          (NameSpaceDecl*)mNameSpaceStack.ElementAt(index2);
        prefixOK = (decl2->mPrefix != decl->mPrefix);
      }
      
      if (prefixOK) {
        uriMatch = PR_TRUE;
        closestURIMatch.Assign(decl->mPrefix);
      }
    }
    
    --index;
  }

  // At this point the following invariants hold:
  // 1) There is nothing on the namespace stack that matches the pair
  //    (aPrefix, aURI)
  // 2) There is nothing on the namespace stack that has aPrefix as the prefix
  //    and a _different_ URI, except for the case aPrefix.IsEmpty (and
  //    possible default namespaces on ancestors)
  // 3) The prefix in closestURIMatch is mapped to aURI in our scope if
  //    uriMatch is set.
  
  // So if uriMatch is set it's OK to use the closestURIMatch prefix.  The one
  // exception is when closestURIMatch is actually empty (default namespace
  // decl) and we must have a prefix.
  if (uriMatch && (!aMustHavePrefix || !closestURIMatch.IsEmpty())) {
    aPrefix.Assign(closestURIMatch);
    return PR_FALSE;
  }
  
  // At this point, if aPrefix is empty (which means we never had a prefix to
  // start with) and we must have a prefix, just generate a new prefix and then
  // send it back through the namespace stack checks to make sure it's OK.
  if (aPrefix.IsEmpty() && aMustHavePrefix) {
    GenerateNewPrefix(aPrefix);
    return ConfirmPrefix(aPrefix, aURI, aElement, aMustHavePrefix);
  }
  // else we will just set aURI as the new default namespace URI

  // Indicate that we need to create a namespace decl for the
  // final prefix
  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHTMLContentSerializer::EndIndentation ( nsIAtom aName,
PRBool  aHasDirtyAttr,
nsAString &  aStr 
) [protected]

Definition at line 1204 of file nsHTMLContentSerializer.cpp.

{
  if ((aName == nsHTMLAtoms::head) ||
      (aName == nsHTMLAtoms::table) ||
      (aName == nsHTMLAtoms::tr) ||
      (aName == nsHTMLAtoms::ul) ||
      (aName == nsHTMLAtoms::ol) ||
      (aName == nsHTMLAtoms::dl) ||
      (aName == nsHTMLAtoms::li) ||
      (aName == nsHTMLAtoms::tbody) ||
      (aName == nsHTMLAtoms::form) ||
      (aName == nsHTMLAtoms::blockquote) ||
      (aName == nsHTMLAtoms::dt) ||
      (aName == nsHTMLAtoms::dd) ||
      (aName == nsHTMLAtoms::frameset)) {
    mIndent--;
  }

  if ((mDoFormat || aHasDirtyAttr) && !mPreLevel && !mColPos) {
    for (PRInt32 i = mIndent; --i >= 0; ) {
      AppendToString(kIndentStr, aStr);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsHTMLContentSerializer::EscapeURI ( const nsAString &  aURI,
nsAString &  aEscapedURI 
) [protected]

Definition at line 496 of file nsHTMLContentSerializer.cpp.

{
  // URL escape %xx cannot be used in JS.
  // No escaping if the scheme is 'javascript'.
  if (IsJavaScript(nsHTMLAtoms::href, aURI)) {
    aEscapedURI = aURI;
    return NS_OK;
  }

  // nsITextToSubURI does charset convert plus uri escape
  // This is needed to convert to a document charset which is needed to support existing browsers.
  // But we eventually want to use UTF-8 instead of a document charset, then the code would be much simpler.
  // See HTML 4.01 spec, "Appendix B.2.1 Non-ASCII characters in URI attribute values"
  nsCOMPtr<nsITextToSubURI> textToSubURI;
  nsAutoString uri(aURI); // in order to use FindCharInSet()
  nsresult rv = NS_OK;


  if (!mCharSet.IsEmpty() && !IsASCII(uri)) {
    textToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  PRInt32 start = 0;
  PRInt32 end;
  nsAutoString part;
  nsXPIDLCString escapedURI;
  aEscapedURI.Truncate(0);

  // Loop and escape parts by avoiding escaping reserved characters (and '%', '#' ).
  while ((end = uri.FindCharInSet("%#;/?:@&=+$,", start)) != -1) {
    part = Substring(aURI, start, (end-start));
    if (textToSubURI && !IsASCII(part)) {
      rv = textToSubURI->ConvertAndEscape(mCharSet.get(), part.get(), getter_Copies(escapedURI));
      NS_ENSURE_SUCCESS(rv, rv);
    }
    else {
      escapedURI.Adopt(nsEscape(NS_ConvertUCS2toUTF8(part).get(), url_Path));
    }
    AppendASCIItoUTF16(escapedURI, aEscapedURI);

    // Append a reserved character without escaping.
    part = Substring(aURI, end, 1);
    aEscapedURI.Append(part);
    start = end + 1;
  }

  if (start < (PRInt32) aURI.Length()) {
    // Escape the remaining part.
    part = Substring(aURI, start, aURI.Length()-start);
    if (textToSubURI) {
      rv = textToSubURI->ConvertAndEscape(mCharSet.get(), part.get(), getter_Copies(escapedURI));
      NS_ENSURE_SUCCESS(rv, rv);
    }
    else {
      escapedURI.Adopt(nsEscape(NS_ConvertUCS2toUTF8(part).get(), url_Path));
    }
    AppendASCIItoUTF16(escapedURI, aEscapedURI);
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHOD nsXMLContentSerializer::Flush ( nsAString &  aStr) [inline, virtual, inherited]

Implements nsIContentSerializer.

Definition at line 83 of file nsXMLContentSerializer.h.

{ return NS_OK; }
void nsXMLContentSerializer::GenerateNewPrefix ( nsAString &  aPrefix) [protected, inherited]

GenerateNewPrefix generates a new prefix and writes it to aPrefix.

Definition at line 440 of file nsXMLContentSerializer.cpp.

{
  aPrefix.AssignLiteral("a");
  char buf[128];
  PR_snprintf(buf, sizeof(buf), "%d", mPrefixIndex++);
  AppendASCIItoUTF16(buf, aPrefix);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsHTMLContentSerializer::HasLongLines ( const nsString text,
PRInt32 aLastNewlineOffset 
) [protected]

Definition at line 1235 of file nsHTMLContentSerializer.cpp.

{
  PRUint32 start=0;
  PRUint32 theLen=text.Length();
  PRBool rv = PR_FALSE;
  aLastNewlineOffset = kNotFound;
  for (start = 0; start < theLen; )
  {
    PRInt32 eol = text.FindChar('\n', start);
    if (eol < 0) {
      eol = text.Length();
    }
    else {
      aLastNewlineOffset = eol;
    }
    if (PRInt32(eol - start) > kLongLineLen)
      rv = PR_TRUE;
    start = eol+1;
  }
  return rv;
}

Here is the caller graph for this function:

NS_IMETHODIMP nsHTMLContentSerializer::Init ( PRUint32  flags,
PRUint32  aWrapColumn,
const char *  aCharSet,
PRBool  aIsCopying 
) [virtual]

Reimplemented from nsXMLContentSerializer.

Definition at line 107 of file nsHTMLContentSerializer.cpp.

{
  mFlags = aFlags;
  if (!aWrapColumn) {
    mMaxColumn = 72;
  }
  else {
    mMaxColumn = aWrapColumn;
  }

  mIsCopying = aIsCopying;
  mIsFirstChildOfOL = PR_FALSE;
  mDoFormat = (mFlags & nsIDocumentEncoder::OutputFormatted) ? PR_TRUE
                                                             : PR_FALSE;
  mBodyOnly = (mFlags & nsIDocumentEncoder::OutputBodyOnly) ? PR_TRUE
                                                            : PR_FALSE;
  // Set the line break character:
  if ((mFlags & nsIDocumentEncoder::OutputCRLineBreak)
      && (mFlags & nsIDocumentEncoder::OutputLFLineBreak)) { // Windows
    mLineBreak.AssignLiteral("\r\n");
  }
  else if (mFlags & nsIDocumentEncoder::OutputCRLineBreak) { // Mac
    mLineBreak.AssignLiteral("\r");
  }
  else if (mFlags & nsIDocumentEncoder::OutputLFLineBreak) { // Unix/DOM
    mLineBreak.AssignLiteral("\n");
  }
  else {
    mLineBreak.AssignLiteral(NS_LINEBREAK);         // Platform/default
  }

  mPreLevel = 0;

  mCharSet = aCharSet;

  // set up entity converter if we are going to need it
  if (mFlags & nsIDocumentEncoder::OutputEncodeW3CEntities) {
    mEntityConverter = do_CreateInstance(NS_ENTITYCONVERTER_CONTRACTID);
  }

  return NS_OK;
}

Here is the call graph for this function:

Definition at line 1326 of file nsHTMLContentSerializer.cpp.

                                                                {
  nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
  nsAutoString parentName;
  {
    nsCOMPtr<nsIDOMNode> parentNode;
    node->GetParentNode(getter_AddRefs(parentNode));
    if (parentNode)
      parentNode->GetNodeName(parentName);
    else
      return PR_FALSE;
  }
  
  if (parentName.LowerCaseEqualsLiteral("ol")) {
    olState defaultOLState(0, PR_FALSE);
    olState* state = nsnull;
    if (mOLStateStack.Count() > 0) 
      state = (olState*)mOLStateStack.ElementAt(mOLStateStack.Count()-1);
    /* Though we should never reach to a "state" as null at this point as 
    all LI are supposed to be inside some OL and OL tag should have pushed
    a state to the mOLStateStack.*/
    if (!state)
      state = &defaultOLState;
    
    if (state->isFirstListItem)
      return PR_TRUE;

    return PR_FALSE;
  }
  else
    return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsHTMLContentSerializer::IsJavaScript ( nsIAtom aAttrNameAtom,
const nsAString &  aAttrValueString 
) [protected]

Definition at line 456 of file nsHTMLContentSerializer.cpp.

{
  if (aAttrNameAtom == nsHTMLAtoms::href ||
      aAttrNameAtom == nsHTMLAtoms::src) {
    static const char kJavaScript[] = "javascript";
    PRInt32 pos = aValueString.FindChar(':');
    if (pos < (PRInt32)(sizeof kJavaScript - 1))
        return PR_FALSE;
    nsAutoString scheme(Substring(aValueString, 0, pos));
    scheme.StripWhitespace();
    if ((scheme.Length() == (sizeof kJavaScript - 1)) &&
        scheme.EqualsIgnoreCase(kJavaScript))
      return PR_TRUE;
    else
      return PR_FALSE;  
  }

  PRBool result = 
                 (aAttrNameAtom == nsLayoutAtoms::onblur)      || (aAttrNameAtom == nsLayoutAtoms::onchange)
              || (aAttrNameAtom == nsLayoutAtoms::onclick)     || (aAttrNameAtom == nsLayoutAtoms::ondblclick)
              || (aAttrNameAtom == nsLayoutAtoms::onfocus)     || (aAttrNameAtom == nsLayoutAtoms::onkeydown)
              || (aAttrNameAtom == nsLayoutAtoms::onkeypress)  || (aAttrNameAtom == nsLayoutAtoms::onkeyup)
              || (aAttrNameAtom == nsLayoutAtoms::onload)      || (aAttrNameAtom == nsLayoutAtoms::onmousedown)
              || (aAttrNameAtom == nsLayoutAtoms::onpageshow)  || (aAttrNameAtom == nsLayoutAtoms::onpagehide)
              || (aAttrNameAtom == nsLayoutAtoms::onmousemove) || (aAttrNameAtom == nsLayoutAtoms::onmouseout)
              || (aAttrNameAtom == nsLayoutAtoms::onmouseover) || (aAttrNameAtom == nsLayoutAtoms::onmouseup)
              || (aAttrNameAtom == nsLayoutAtoms::onreset)     || (aAttrNameAtom == nsLayoutAtoms::onselect)
              || (aAttrNameAtom == nsLayoutAtoms::onsubmit)    || (aAttrNameAtom == nsLayoutAtoms::onunload)
              || (aAttrNameAtom == nsLayoutAtoms::onabort)     || (aAttrNameAtom == nsLayoutAtoms::onerror)
              || (aAttrNameAtom == nsLayoutAtoms::onpaint)     || (aAttrNameAtom == nsLayoutAtoms::onresize)
              || (aAttrNameAtom == nsLayoutAtoms::onscroll)    || (aAttrNameAtom == nsLayoutAtoms::onbroadcast)
              || (aAttrNameAtom == nsLayoutAtoms::onclose)     || (aAttrNameAtom == nsLayoutAtoms::oncontextmenu)
              || (aAttrNameAtom == nsLayoutAtoms::oncommand)   || (aAttrNameAtom == nsLayoutAtoms::oncommandupdate)
              || (aAttrNameAtom == nsLayoutAtoms::ondragdrop)  || (aAttrNameAtom == nsLayoutAtoms::ondragenter)
              || (aAttrNameAtom == nsLayoutAtoms::ondragexit)  || (aAttrNameAtom == nsLayoutAtoms::ondraggesture)
              || (aAttrNameAtom == nsLayoutAtoms::ondragover)  || (aAttrNameAtom == nsLayoutAtoms::oninput);
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsXMLContentSerializer::IsShorthandAttr ( const nsIAtom aAttrName,
const nsIAtom aElementName 
) [protected, inherited]

Definition at line 804 of file nsXMLContentSerializer.cpp.

{
  // checked
  if ((aAttrName == nsHTMLAtoms::checked) &&
      (aElementName == nsHTMLAtoms::input)) {
    return PR_TRUE;
  }

  // compact
  if ((aAttrName == nsHTMLAtoms::compact) &&
      (aElementName == nsHTMLAtoms::dir || 
       aElementName == nsHTMLAtoms::dl ||
       aElementName == nsHTMLAtoms::menu ||
       aElementName == nsHTMLAtoms::ol ||
       aElementName == nsHTMLAtoms::ul)) {
    return PR_TRUE;
  }

  // declare
  if ((aAttrName == nsHTMLAtoms::declare) &&
      (aElementName == nsHTMLAtoms::object)) {
    return PR_TRUE;
  }

  // defer
  if ((aAttrName == nsHTMLAtoms::defer) &&
      (aElementName == nsHTMLAtoms::script)) {
    return PR_TRUE;
  }

  // disabled
  if ((aAttrName == nsHTMLAtoms::disabled) &&
      (aElementName == nsHTMLAtoms::button ||
       aElementName == nsHTMLAtoms::input ||
       aElementName == nsHTMLAtoms::optgroup ||
       aElementName == nsHTMLAtoms::option ||
       aElementName == nsHTMLAtoms::select ||
       aElementName == nsHTMLAtoms::textarea)) {
    return PR_TRUE;
  }

  // ismap
  if ((aAttrName == nsHTMLAtoms::ismap) &&
      (aElementName == nsHTMLAtoms::img ||
       aElementName == nsHTMLAtoms::input)) {
    return PR_TRUE;
  }

  // multiple
  if ((aAttrName == nsHTMLAtoms::multiple) &&
      (aElementName == nsHTMLAtoms::select)) {
    return PR_TRUE;
  }

  // noresize
  if ((aAttrName == nsHTMLAtoms::noresize) &&
      (aElementName == nsHTMLAtoms::frame)) {
    return PR_TRUE;
  }

  // noshade
  if ((aAttrName == nsHTMLAtoms::noshade) &&
      (aElementName == nsHTMLAtoms::hr)) {
    return PR_TRUE;
  }

  // nowrap
  if ((aAttrName == nsHTMLAtoms::nowrap) &&
      (aElementName == nsHTMLAtoms::td ||
       aElementName == nsHTMLAtoms::th)) {
    return PR_TRUE;
  }

  // readonly
  if ((aAttrName == nsHTMLAtoms::readonly) &&
      (aElementName == nsHTMLAtoms::input ||
       aElementName == nsHTMLAtoms::textarea)) {
    return PR_TRUE;
  }

  // selected
  if ((aAttrName == nsHTMLAtoms::selected) &&
      (aElementName == nsHTMLAtoms::option)) {
    return PR_TRUE;
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsHTMLContentSerializer::LineBreakAfterClose ( nsIAtom aName,
PRBool  aHasDirtyAttr 
) [protected]

Definition at line 1134 of file nsHTMLContentSerializer.cpp.

{
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel ||
      (mFlags & nsIDocumentEncoder::OutputRaw)) {
    return PR_FALSE;
  }

  if ((aName == nsHTMLAtoms::html) ||
      (aName == nsHTMLAtoms::head) ||
      (aName == nsHTMLAtoms::body) ||
      (aName == nsHTMLAtoms::tr) ||
      (aName == nsHTMLAtoms::th) ||
      (aName == nsHTMLAtoms::td) ||
      (aName == nsHTMLAtoms::pre) ||
      (aName == nsHTMLAtoms::title) ||
      (aName == nsHTMLAtoms::li) ||
      (aName == nsHTMLAtoms::dt) ||
      (aName == nsHTMLAtoms::dd) ||
      (aName == nsHTMLAtoms::blockquote) ||
      (aName == nsHTMLAtoms::select) ||
      (aName == nsHTMLAtoms::option) ||
      (aName == nsHTMLAtoms::p) ||
      (aName == nsHTMLAtoms::map) ||
      (aName == nsHTMLAtoms::div)) {
    return PR_TRUE;
  }
  else {
    nsIParserService* parserService =
      nsContentUtils::GetParserServiceWeakRef();
    
    if (parserService) {
      PRBool res;
      parserService->IsBlock(parserService->HTMLAtomTagToId(aName), res);
      return res;
    }
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsHTMLContentSerializer::LineBreakAfterOpen ( nsIAtom aName,
PRBool  aHasDirtyAttr 
) [protected]

Definition at line 1078 of file nsHTMLContentSerializer.cpp.

{
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel ||
      (mFlags & nsIDocumentEncoder::OutputRaw)) {
    return PR_FALSE;
  }

  if ((aName == nsHTMLAtoms::html) ||
      (aName == nsHTMLAtoms::head) ||
      (aName == nsHTMLAtoms::body) ||
      (aName == nsHTMLAtoms::ul) ||
      (aName == nsHTMLAtoms::ol) ||
      (aName == nsHTMLAtoms::dl) ||
      (aName == nsHTMLAtoms::table) ||
      (aName == nsHTMLAtoms::tbody) ||
      (aName == nsHTMLAtoms::tr) ||
      (aName == nsHTMLAtoms::br) ||
      (aName == nsHTMLAtoms::meta) ||
      (aName == nsHTMLAtoms::link) ||
      (aName == nsHTMLAtoms::script) ||
      (aName == nsHTMLAtoms::select) ||
      (aName == nsHTMLAtoms::map) ||
      (aName == nsHTMLAtoms::area) ||
      (aName == nsHTMLAtoms::style)) {
    return PR_TRUE;
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsHTMLContentSerializer::LineBreakBeforeClose ( nsIAtom aName,
PRBool  aHasDirtyAttr 
) [protected]

Definition at line 1110 of file nsHTMLContentSerializer.cpp.

{
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos ||
      (mFlags & nsIDocumentEncoder::OutputRaw)) {
    return PR_FALSE;
  }

  if ((aName == nsHTMLAtoms::html) ||
      (aName == nsHTMLAtoms::head) ||
      (aName == nsHTMLAtoms::body) ||
      (aName == nsHTMLAtoms::ul) ||
      (aName == nsHTMLAtoms::ol) ||
      (aName == nsHTMLAtoms::dl) ||
      (aName == nsHTMLAtoms::select) ||
      (aName == nsHTMLAtoms::table) ||
      (aName == nsHTMLAtoms::tbody)) {
    return PR_TRUE;
  }
  
  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsHTMLContentSerializer::LineBreakBeforeOpen ( nsIAtom aName,
PRBool  aHasDirtyAttr 
) [protected]

Definition at line 1045 of file nsHTMLContentSerializer.cpp.

{
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos ||
      (mFlags & nsIDocumentEncoder::OutputRaw)) {
    return PR_FALSE;
  }
        
  if (aName == nsHTMLAtoms::title ||
      aName == nsHTMLAtoms::meta  ||
      aName == nsHTMLAtoms::link  ||
      aName == nsHTMLAtoms::style ||
      aName == nsHTMLAtoms::select ||
      aName == nsHTMLAtoms::option ||
      aName == nsHTMLAtoms::script ||
      aName == nsHTMLAtoms::html) {
    return PR_TRUE;
  }
  else {
    nsIParserService* parserService =
      nsContentUtils::GetParserServiceWeakRef();
    
    if (parserService) {
      PRBool res;
      parserService->IsBlock(parserService->HTMLAtomTagToId(aName), res);
      return res;
    }
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXMLContentSerializer::MaybeAddNewline ( nsAString &  aStr) [protected, inherited]

Definition at line 895 of file nsXMLContentSerializer.cpp.

{
  if (mAddNewline) {
    aStr.Append((PRUnichar)'\n');
    mAddNewline = PR_FALSE;
  }
}

Here is the caller graph for this function:

void nsXMLContentSerializer::MaybeFlagNewline ( nsIDOMNode aNode) [protected, inherited]

Definition at line 904 of file nsXMLContentSerializer.cpp.

{
  nsCOMPtr<nsIDOMNode> parent;
  aNode->GetParentNode(getter_AddRefs(parent));
  if (parent) {
    PRUint16 type;
    parent->GetNodeType(&type);
    mAddNewline = type == nsIDOMNode::DOCUMENT_NODE;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXMLContentSerializer::PopNameSpaceDeclsFor ( nsIDOMElement aOwner) [protected, inherited]

Definition at line 319 of file nsXMLContentSerializer.cpp.

{
  PRInt32 index, count;

  count = mNameSpaceStack.Count();
  for (index = count - 1; index >= 0; index--) {
    NameSpaceDecl* decl = (NameSpaceDecl*)mNameSpaceStack.ElementAt(index);
    if (decl->mOwner != aOwner) {
      break;
    }
    mNameSpaceStack.RemoveElementAt(index);
    delete decl;
  }
}

Here is the caller graph for this function:

nsresult nsXMLContentSerializer::PushNameSpaceDecl ( const nsAString &  aPrefix,
const nsAString &  aURI,
nsIDOMElement aOwner 
) [protected, virtual, inherited]

Definition at line 301 of file nsXMLContentSerializer.cpp.

{
  NameSpaceDecl* decl = new NameSpaceDecl();
  if (!decl) return NS_ERROR_OUT_OF_MEMORY;

  decl->mPrefix.Assign(aPrefix);
  decl->mURI.Assign(aURI);
  // Don't addref - this weak reference will be removed when
  // we pop the stack
  decl->mOwner = aOwner;

  mNameSpaceStack.AppendElement((void*)decl);
  return NS_OK;
}

Here is the caller graph for this function:

void nsXMLContentSerializer::SerializeAttr ( const nsAString &  aPrefix,
const nsAString &  aName,
const nsAString &  aValue,
nsAString &  aStr,
PRBool  aDoEscapeEntities 
) [protected, inherited]

Definition at line 449 of file nsXMLContentSerializer.cpp.

{
  AppendToString(PRUnichar(' '), aStr);
  if (!aPrefix.IsEmpty()) {
    AppendToString(aPrefix, aStr);
    AppendToString(PRUnichar(':'), aStr);
  }
  AppendToString(aName, aStr);
  
  if ( aDoEscapeEntities ) {
    // if problem characters are turned into character entity references
    // then there will be no problem with the value delimiter characters
    AppendToString(NS_LITERAL_STRING("=\""), aStr);

    mInAttribute = PR_TRUE;
    AppendToString(aValue, aStr, PR_TRUE);
    mInAttribute = PR_FALSE;

    AppendToString(PRUnichar('"'), aStr);
  }
  else {
    // Depending on whether the attribute value contains quotes or apostrophes we
    // need to select the delimiter character and escape characters using
    // character entity references, ignoring the value of aDoEscapeEntities.
    // See http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2.2 for
    // the standard on character entity references in values. 
    PRBool bIncludesSingle = PR_FALSE;
    PRBool bIncludesDouble = PR_FALSE;
    nsAString::const_iterator iCurr, iEnd;
    PRUint32 uiSize, i;
    aValue.BeginReading(iCurr);
    aValue.EndReading(iEnd);
    for ( ; iCurr != iEnd; iCurr.advance(uiSize) ) {
      const PRUnichar * buf = iCurr.get();
      uiSize = iCurr.size_forward();
      for ( i = 0; i < uiSize; i++, buf++ ) {
        if ( *buf == PRUnichar('\'') )
        {
          bIncludesSingle = PR_TRUE;
          if ( bIncludesDouble ) break;
        }
        else if ( *buf == PRUnichar('"') )
        {
          bIncludesDouble = PR_TRUE;
          if ( bIncludesSingle ) break;
        }
      }
      // if both have been found we don't need to search further
      if ( bIncludesDouble && bIncludesSingle ) break;
    }

    // Delimiter and escaping is according to the following table
    //    bIncludesDouble     bIncludesSingle     Delimiter       Escape Double Quote
    //    FALSE               FALSE               "               FALSE
    //    FALSE               TRUE                "               FALSE
    //    TRUE                FALSE               '               FALSE
    //    TRUE                TRUE                "               TRUE
    PRUnichar cDelimiter = 
        (bIncludesDouble && !bIncludesSingle) ? PRUnichar('\'') : PRUnichar('"');
    AppendToString(PRUnichar('='), aStr);
    AppendToString(cDelimiter, aStr);
    if (bIncludesDouble && bIncludesSingle) {
      nsAutoString sValue(aValue);
      sValue.ReplaceSubstring(NS_LITERAL_STRING("\"").get(), NS_LITERAL_STRING("&quot;").get());
      mInAttribute = PR_TRUE;
      AppendToString(sValue, aStr, PR_FALSE);
      mInAttribute = PR_FALSE;
    }
    else {
      mInAttribute = PR_TRUE;
      AppendToString(aValue, aStr, PR_FALSE);
      mInAttribute = PR_FALSE;
    }
    AppendToString(cDelimiter, aStr);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHTMLContentSerializer::SerializeAttributes ( nsIContent aContent,
nsIAtom aTagName,
nsAString &  aStr 
) [protected]

Definition at line 560 of file nsHTMLContentSerializer.cpp.

{
  nsresult rv;
  PRUint32 index, count;
  nsAutoString nameStr, valueStr;
  PRInt32 namespaceID;
  nsCOMPtr<nsIAtom> attrName, attrPrefix;

  count = aContent->GetAttrCount();

  NS_NAMED_LITERAL_STRING(_mozStr, "_moz");

  // Loop backward over the attributes, since the order they are stored in is
  // the opposite of the order they were parsed in (see bug 213347 for reason).
  // index is unsigned, hence index >= 0 is always true.
  for (index = count; index > 0; ) {
    --index;
    aContent->GetAttrNameAt(index, 
                            &namespaceID,
                            getter_AddRefs(attrName),
                            getter_AddRefs(attrPrefix));

    // Filter out any attribute starting with [-|_]moz
    const char* sharedName;
    attrName->GetUTF8String(&sharedName);
    if ((('_' == *sharedName) || ('-' == *sharedName)) &&
        !nsCRT::strncmp(sharedName+1, kMozStr, PRUint32(sizeof(kMozStr)-1))) {
      continue;
    }
    aContent->GetAttr(namespaceID, attrName, valueStr);

    // 
    // Filter out special case of <br type="_moz"> or <br _moz*>,
    // used by the editor.  Bug 16988.  Yuck.
    //
    if (aTagName == nsHTMLAtoms::br && attrName == nsHTMLAtoms::type &&
        StringBeginsWith(valueStr, _mozStr)) {
      continue;
    }

    if (mIsCopying && mIsFirstChildOfOL && (aTagName == nsHTMLAtoms::li) && 
        (attrName == nsHTMLAtoms::value)){
      // This is handled separately in SerializeLIValueAttribute()
      continue;
    }
    PRBool isJS = IsJavaScript(attrName, valueStr);
    
    if (((attrName == nsHTMLAtoms::href) || 
         (attrName == nsHTMLAtoms::src))) {
      // Make all links absolute when converting only the selection:
      if (mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) {
        // Would be nice to handle OBJECT and APPLET tags,
        // but that gets more complicated since we have to
        // search the tag list for CODEBASE as well.
        // For now, just leave them relative.
        nsCOMPtr<nsIURI> uri = aContent->GetBaseURI();
        if (uri) {
          nsAutoString absURI;
          rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
          if (NS_SUCCEEDED(rv)) {
            valueStr = absURI;
          }
        }
      }
      // Need to escape URI.
      nsAutoString tempURI(valueStr);
      if (!isJS && NS_FAILED(EscapeURI(tempURI, valueStr)))
        valueStr = tempURI;
    }

    attrName->ToString(nameStr);
    
    /*If we already crossed the MaxColumn limit or 
    * if this attr name-value pair(including a space,=,opening and closing quotes) is greater than MaxColumn limit
    * then start the attribute from a new line.
    */

    if (mDoFormat
        && (mColPos >= mMaxColumn
            || ((PRInt32)(mColPos + nameStr.Length() +
                          valueStr.Length() + 4) > mMaxColumn))) {
        aStr.Append(mLineBreak);
        mColPos = 0;
    }

    // Expand shorthand attribute.
    if (IsShorthandAttr(attrName, aTagName) && valueStr.IsEmpty()) {
      valueStr = nameStr;
    }
    SerializeAttr(EmptyString(), nameStr, valueStr, aStr, !isJS);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHTMLContentSerializer::SerializeLIValueAttribute ( nsIDOMElement aElement,
nsAString &  aStr 
) [protected]

Definition at line 1258 of file nsHTMLContentSerializer.cpp.

{
  // We are copying and we are at the "first" LI node of OL in selected range.
  // It may not be the first LI child of OL but it's first in the selected range.
  // Note that we get into this condition only once per a OL.
  nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
  PRBool found = PR_FALSE;
  nsIDOMNode* currNode = node;
  nsAutoString valueStr;
  PRInt32 offset = 0;
  olState defaultOLState(0, PR_FALSE);
  olState* state = nsnull;
  if (mOLStateStack.Count() > 0) 
    state = (olState*)mOLStateStack.ElementAt(mOLStateStack.Count()-1);
  /* Though we should never reach to a "state" as null or mOLStateStack.Count() == 0 
  at this point as all LI are supposed to be inside some OL and OL tag should have 
  pushed a state to the olStateStack.*/
  if (!state || mOLStateStack.Count() == 0)
    state = &defaultOLState;
  PRInt32 startVal = state->startVal;
  state->isFirstListItem = PR_FALSE;
  // Traverse previous siblings until we find one with "value" attribute.
  // offset keeps track of how many previous siblings we had tocurrNode traverse.
  while (currNode && !found) {
    nsCOMPtr<nsIDOMElement> currElement = do_QueryInterface(currNode);
    // currElement may be null if it were a text node.
    if (currElement) {
      nsAutoString tagName;
      currElement->GetTagName(tagName);
      if (tagName.LowerCaseEqualsLiteral("li")) {
        currElement->GetAttribute(NS_LITERAL_STRING("value"), valueStr);
        if (valueStr.IsEmpty())
          offset++;
        else {
          found = PR_TRUE;
          PRInt32 rv = 0;
          startVal = valueStr.ToInteger(&rv); 
        }
      }
    }
    currNode->GetPreviousSibling(&currNode);
  }
  // If LI was not having "value", Set the "value" attribute for it.
  // Note that We are at the first LI in the selected range of OL.
  if (offset == 0 && found) {
    // offset = 0 => LI itself has the value attribute and we did not need to traverse back.
    // Just serialize value attribute like other tags.
    SerializeAttr(EmptyString(), NS_LITERAL_STRING("value"), valueStr, aStr, PR_FALSE);
  }
  else if (offset == 1 && !found) {
    /*(offset = 1 && !found) means either LI is the first child node of OL 
    and LI is not having "value" attribute. 
    In that case we would not like to set "value" attribute to reduce the changes.
    */
     //do nothing...
  }
  else if (offset > 0) {
    // Set value attribute.
    nsAutoString valueStr;

    //As serializer needs to use this valueAttr we are creating here, 
    valueStr.AppendInt(startVal + offset);
    SerializeAttr(EmptyString(), NS_LITERAL_STRING("value"), valueStr, aStr, PR_FALSE);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHTMLContentSerializer::StartIndentation ( nsIAtom aName,
PRBool  aHasDirtyAttr,
nsAString &  aStr 
) [protected]

Definition at line 1176 of file nsHTMLContentSerializer.cpp.

{
  if ((mDoFormat || aHasDirtyAttr) && !mPreLevel && !mColPos) {
    for (PRInt32 i = mIndent; --i >= 0; ) {
      AppendToString(kIndentStr, aStr);
    }
  }

  if ((aName == nsHTMLAtoms::head) ||
      (aName == nsHTMLAtoms::table) ||
      (aName == nsHTMLAtoms::tr) ||
      (aName == nsHTMLAtoms::ul) ||
      (aName == nsHTMLAtoms::ol) ||
      (aName == nsHTMLAtoms::dl) ||
      (aName == nsHTMLAtoms::tbody) ||
      (aName == nsHTMLAtoms::form) ||
      (aName == nsHTMLAtoms::frameset) ||
      (aName == nsHTMLAtoms::blockquote) ||
      (aName == nsHTMLAtoms::li) ||
      (aName == nsHTMLAtoms::dt) ||
      (aName == nsHTMLAtoms::dd)) {
    mIndent++;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 151 of file nsXMLContentSerializer.h.

Definition at line 133 of file nsHTMLContentSerializer.h.

Definition at line 127 of file nsHTMLContentSerializer.h.

Definition at line 157 of file nsHTMLContentSerializer.h.

Definition at line 121 of file nsHTMLContentSerializer.h.

Definition at line 125 of file nsHTMLContentSerializer.h.

Definition at line 126 of file nsHTMLContentSerializer.h.

Definition at line 118 of file nsHTMLContentSerializer.h.

Definition at line 122 of file nsHTMLContentSerializer.h.

Definition at line 150 of file nsXMLContentSerializer.h.

Definition at line 123 of file nsHTMLContentSerializer.h.

Definition at line 149 of file nsHTMLContentSerializer.h.

Definition at line 120 of file nsHTMLContentSerializer.h.

Definition at line 128 of file nsHTMLContentSerializer.h.

Definition at line 137 of file nsHTMLContentSerializer.h.

Definition at line 155 of file nsHTMLContentSerializer.h.

Definition at line 152 of file nsHTMLContentSerializer.h.

Definition at line 154 of file nsHTMLContentSerializer.h.

Definition at line 134 of file nsHTMLContentSerializer.h.

Definition at line 149 of file nsXMLContentSerializer.h.

Definition at line 150 of file nsHTMLContentSerializer.h.

nsAutoVoidArray nsHTMLContentSerializer::mOLStateStack [protected]

Definition at line 168 of file nsHTMLContentSerializer.h.

Definition at line 148 of file nsXMLContentSerializer.h.

Definition at line 138 of file nsHTMLContentSerializer.h.


The documentation for this class was generated from the following files: