/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * nsIContentSerializer implementation that can be used with an * nsIDocumentEncoder to convert an XML DOM to an XML string that * could be parsed into more or less the original DOM. */ #ifndef nsXMLContentSerializer_h__ #define nsXMLContentSerializer_h__ #include "mozilla/Attributes.h" #include "nsIContentSerializer.h" #include "nsISupportsUtils.h" #include "nsCOMPtr.h" #include "nsTArray.h" #include "nsString.h" #define kIndentStr NS_LITERAL_STRING(" ") #define kEndTag NS_LITERAL_STRING("' at the end of the start * tag, possibly preceded by '/' and maybe a ' ' before that too. * * aElement and aOriginalElement are the same as the corresponding arguments * to AppendElementStart. */ MOZ_MUST_USE bool AppendEndOfElementStart(mozilla::dom::Element* aEleemnt, mozilla::dom::Element* aOriginalElement, nsAString& aStr); /** * This method can be redefine to serialize additional things just after * after the serialization ot the start tag. * (called at the end of AppendElementStart) */ MOZ_MUST_USE virtual bool AfterElementStart(nsIContent* aContent, nsIContent* aOriginalElement, nsAString& aStr) { return true; }; /** * This method can be redefined to check if the element can be serialized. * It is called when the serialization of the end tag is asked * (AppendElementEnd) * In this method you can also force the formating * by setting aForceFormat to true. * @return boolean true if the element can be output */ virtual bool CheckElementEnd(mozilla::dom::Element* aElement, mozilla::dom::Element* aOriginalElement, bool& aForceFormat, nsAString& aStr); /** * This method can be redefine to serialize additional things just after * after the serialization ot the end tag. * (called at the end of AppendElementStart) */ virtual void AfterElementEnd(nsIContent * aContent, nsAString& aStr) { }; /** * Returns true if a line break should be inserted before an element open tag */ virtual bool LineBreakBeforeOpen(int32_t aNamespaceID, nsIAtom* aName); /** * Returns true if a line break should be inserted after an element open tag */ virtual bool LineBreakAfterOpen(int32_t aNamespaceID, nsIAtom* aName); /** * Returns true if a line break should be inserted after an element close tag */ virtual bool LineBreakBeforeClose(int32_t aNamespaceID, nsIAtom* aName); /** * Returns true if a line break should be inserted after an element close tag */ virtual bool LineBreakAfterClose(int32_t aNamespaceID, nsIAtom* aName); /** * add intendation. Call only in the case of formating and if the current * position is at 0. It updates the column position. */ MOZ_MUST_USE bool AppendIndentation(nsAString& aStr); MOZ_MUST_USE bool IncrIndentation(nsIAtom* aName); void DecrIndentation(nsIAtom* aName); // Functions to check for newlines that needs to be added between nodes in // the root of a document. See mAddNewlineForRootNode MOZ_MUST_USE bool MaybeAddNewlineForRootNode(nsAString& aStr); void MaybeFlagNewlineForRootNode(nsINode* aNode); // Functions to check if we enter in or leave from a preformated content virtual void MaybeEnterInPreContent(nsIContent* aNode); virtual void MaybeLeaveFromPreContent(nsIContent* aNode); bool ShouldMaintainPreLevel() const; int32_t PreLevel() const { MOZ_ASSERT(ShouldMaintainPreLevel()); return mPreLevel; } int32_t& PreLevel() { MOZ_ASSERT(ShouldMaintainPreLevel()); return mPreLevel; } int32_t mPrefixIndex; struct NameSpaceDecl { nsString mPrefix; nsString mURI; nsIContent* mOwner; }; nsTArray mNameSpaceStack; // nsIDocumentEncoder flags MOZ_INIT_OUTSIDE_CTOR uint32_t mFlags; // characters to use for line break nsString mLineBreak; // The charset that was passed to Init() nsCString mCharset; // current column position on the current line uint32_t mColPos; // true = pretty formating should be done (OutputFormated flag) MOZ_INIT_OUTSIDE_CTOR bool mDoFormat; // true = no formatting,(OutputRaw flag) // no newline convertion and no rewrap long lines even if OutputWrap is set. MOZ_INIT_OUTSIDE_CTOR bool mDoRaw; // true = wrapping should be done (OutputWrap flag) MOZ_INIT_OUTSIDE_CTOR bool mDoWrap; // true = we can break lines (OutputDisallowLineBreaking flag) MOZ_INIT_OUTSIDE_CTOR bool mAllowLineBreaking; // number of maximum column in a line, in the wrap mode MOZ_INIT_OUTSIDE_CTOR uint32_t mMaxColumn; // current indent value nsString mIndent; // this is the indentation level after the indentation reached // the maximum length of indentation int32_t mIndentOverflow; // says if the indentation has been already added on the current line bool mIsIndentationAddedOnCurrentLine; // the string which is currently added is in an attribute bool mInAttribute; // true = a newline character should be added. It's only // useful when serializing root nodes. see MaybeAddNewlineForRootNode and // MaybeFlagNewlineForRootNode bool mAddNewlineForRootNode; // Indicates that a space will be added if and only if content is // continued on the same line while serializing source. Otherwise, // the newline character acts as the whitespace and no space is needed. // used when mDoFormat = true bool mAddSpace; // says that if the next string to add contains a newline character at the // begining, then this newline character should be ignored, because a // such character has already been added into the output string bool mMayIgnoreLineBreakSequence; bool mBodyOnly; int32_t mInBody; private: // number of nested elements which have preformated content MOZ_INIT_OUTSIDE_CTOR int32_t mPreLevel; }; nsresult NS_NewXMLContentSerializer(nsIContentSerializer** aSerializer); #endif