1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 /*
8  * nsIContentSerializer implementation that can be used with an
9  * nsIDocumentEncoder to convert an XHTML (not HTML!) DOM to an XHTML
10  * string that could be parsed into more or less the original DOM.
11  */
12 
13 #ifndef nsXHTMLContentSerializer_h__
14 #define nsXHTMLContentSerializer_h__
15 
16 #include "mozilla/Attributes.h"
17 #include "nsXMLContentSerializer.h"
18 #include "nsString.h"
19 #include "nsTArray.h"
20 
21 class nsIContent;
22 class nsAtom;
23 
24 namespace mozilla {
25 class Encoding;
26 }
27 
28 class nsXHTMLContentSerializer : public nsXMLContentSerializer {
29  public:
30   nsXHTMLContentSerializer();
31   virtual ~nsXHTMLContentSerializer();
32 
33   NS_IMETHOD Init(uint32_t flags, uint32_t aWrapColumn,
34                   const mozilla::Encoding* aEncoding, bool aIsCopying,
35                   bool aRewriteEncodingDeclaration,
36                   bool* aNeedsPreformatScanning, nsAString& aOutput) override;
37 
38   NS_IMETHOD AppendText(nsIContent* aText, int32_t aStartOffset,
39                         int32_t aEndOffset) override;
40 
41   NS_IMETHOD AppendDocumentStart(mozilla::dom::Document* aDocument) override;
42 
43  protected:
44   virtual bool CheckElementStart(mozilla::dom::Element* aElement,
45                                  bool& aForceFormat, nsAString& aStr,
46                                  nsresult& aResult) override;
47 
48   MOZ_MUST_USE
49   virtual bool AfterElementStart(nsIContent* aContent,
50                                  nsIContent* aOriginalElement,
51                                  nsAString& aStr) override;
52 
53   virtual bool CheckElementEnd(mozilla::dom::Element* aContent,
54                                mozilla::dom::Element* aOriginalElement,
55                                bool& aForceFormat, nsAString& aStr) override;
56 
57   virtual void AfterElementEnd(nsIContent* aContent, nsAString& aStr) override;
58 
59   virtual bool LineBreakBeforeOpen(int32_t aNamespaceID,
60                                    nsAtom* aName) override;
61   virtual bool LineBreakAfterOpen(int32_t aNamespaceID, nsAtom* aName) override;
62   virtual bool LineBreakBeforeClose(int32_t aNamespaceID,
63                                     nsAtom* aName) override;
64   virtual bool LineBreakAfterClose(int32_t aNamespaceID,
65                                    nsAtom* aName) override;
66 
67   bool HasLongLines(const nsString& text, int32_t& aLastNewlineOffset);
68 
69   // functions to check if we enter in or leave from a preformated content
70   virtual void MaybeEnterInPreContent(nsIContent* aNode) override;
71   virtual void MaybeLeaveFromPreContent(nsIContent* aNode) override;
72 
73   MOZ_MUST_USE
74   virtual bool SerializeAttributes(mozilla::dom::Element* aContent,
75                                    mozilla::dom::Element* aOriginalElement,
76                                    nsAString& aTagPrefix,
77                                    const nsAString& aTagNamespaceURI,
78                                    nsAtom* aTagName, nsAString& aStr,
79                                    uint32_t aSkipAttr,
80                                    bool aAddNSAttr) override;
81 
82   bool IsFirstChildOfOL(nsIContent* aElement);
83 
84   MOZ_MUST_USE
85   bool SerializeLIValueAttribute(nsIContent* aElement, nsAString& aStr);
86   bool IsShorthandAttr(const nsAtom* aAttrName, const nsAtom* aElementName);
87 
88   MOZ_MUST_USE
89   virtual bool AppendAndTranslateEntities(const nsAString& aStr,
90                                           nsAString& aOutputStr) override;
91 
92  private:
93   bool IsElementPreformatted(nsIContent* aNode);
94 
95  protected:
96   /*
97    * isHTMLParser should be set to true by the HTML parser which inherits from
98    * this class. It avoids to redefine methods just for few changes.
99    */
100   bool mIsHTMLSerializer;
101 
102   bool mIsCopying;  // Set to true only while copying
103 
104   /*
105    * mDisableEntityEncoding is higher than 0 while the serializer is serializing
106    * the content of a element whose content is considerd CDATA by the
107    * serializer (such elements are 'script', 'style', 'noscript' and
108    * possibly others in XHTML) This doesn't have anything to do with if the
109    * element is defined as CDATA in the DTD, it simply means we'll
110    * output the content of the element without doing any entity encoding
111    * what so ever.
112    */
113   int32_t mDisableEntityEncoding;
114 
115   // This is to ensure that we only do meta tag fixups when dealing with
116   // whole documents.
117   bool mRewriteEncodingDeclaration;
118 
119   // To keep track of First LI child of OL in selected range
120   bool mIsFirstChildOfOL;
121 
122   // To keep track of startvalue of OL and first list item for nested lists
123   struct olState {
olStateolState124     olState(int32_t aStart, bool aIsFirst)
125         : startVal(aStart), isFirstListItem(aIsFirst) {}
126 
olStateolState127     olState(const olState& aOlState) {
128       startVal = aOlState.startVal;
129       isFirstListItem = aOlState.isFirstListItem;
130     }
131 
132     // the value of the start attribute in the OL
133     int32_t startVal;
134 
135     // is true only before the serialization of the first li of an ol
136     // should be false for other li in the list
137     bool isFirstListItem;
138   };
139 
140   // Stack to store one olState struct per <OL>.
141   AutoTArray<olState, 8> mOLStateStack;
142 
143   bool HasNoChildren(nsIContent* aContent);
144 };
145 
146 nsresult NS_NewXHTMLContentSerializer(nsIContentSerializer** aSerializer);
147 
148 #endif
149