Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/xml/nsXMLContentSink.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef nsXMLContentSink_h__
8
#define nsXMLContentSink_h__
9
10
#include "mozilla/Attributes.h"
11
#include "nsContentSink.h"
12
#include "nsIXMLContentSink.h"
13
#include "nsIExpatSink.h"
14
#include "nsIDocumentTransformer.h"
15
#include "nsTArray.h"
16
#include "nsCOMPtr.h"
17
#include "nsCRT.h"
18
#include "nsCycleCollectionParticipant.h"
19
#include "nsIDTD.h"
20
#include "mozilla/dom/FromParser.h"
21
22
class nsIDocument;
23
class nsIURI;
24
class nsIContent;
25
class nsIParser;
26
class nsTextNode;
27
28
namespace mozilla {
29
namespace dom {
30
class NodeInfo;
31
class ProcessingInstruction;
32
} // namespace dom
33
} // namespace mozilla
34
35
typedef enum {
36
  eXMLContentSinkState_InProlog,
37
  eXMLContentSinkState_InDocumentElement,
38
  eXMLContentSinkState_InEpilog
39
} XMLContentSinkState;
40
41
struct StackNode {
42
  nsCOMPtr<nsIContent> mContent;
43
  uint32_t mNumFlushed;
44
};
45
46
class nsXMLContentSink : public nsContentSink,
47
                         public nsIXMLContentSink,
48
                         public nsITransformObserver,
49
                         public nsIExpatSink
50
{
51
public:
52
  nsXMLContentSink();
53
54
  nsresult Init(nsIDocument* aDoc,
55
                nsIURI* aURL,
56
                nsISupports* aContainer,
57
                nsIChannel* aChannel);
58
59
  // nsISupports
60
  NS_DECL_ISUPPORTS_INHERITED
61
62
  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXMLContentSink,
63
                                                     nsContentSink)
64
65
  NS_DECL_NSIEXPATSINK
66
67
  // nsIContentSink
68
  NS_IMETHOD WillParse(void) override;
69
  NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
70
  NS_IMETHOD DidBuildModel(bool aTerminated) override;
71
  NS_IMETHOD WillInterrupt(void) override;
72
  NS_IMETHOD WillResume(void) override;
73
  NS_IMETHOD SetParser(nsParserBase* aParser) override;
74
  virtual void FlushPendingNotifications(mozilla::FlushType aType) override;
75
  virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override;
76
  virtual nsISupports *GetTarget() override;
77
  virtual bool IsScriptExecuting() override;
78
  virtual void ContinueInterruptedParsingAsync() override;
79
80
  // nsITransformObserver
81
  NS_IMETHOD OnDocumentCreated(nsIDocument *aResultDocument) override;
82
  NS_IMETHOD OnTransformDone(nsresult aResult, nsIDocument *aResultDocument) override;
83
84
  // nsICSSLoaderObserver
85
  NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet,
86
                              bool aWasAlternate,
87
                              nsresult aStatus) override;
88
  static bool ParsePIData(const nsString &aData, nsString &aHref,
89
                          nsString &aTitle, nsString &aMedia,
90
                          bool &aIsAlternate);
91
92
protected:
93
  virtual ~nsXMLContentSink();
94
95
  nsIParser* GetParser();
96
97
  void ContinueInterruptedParsingIfEnabled();
98
99
  // Start layout.  If aIgnorePendingSheets is true, this will happen even if
100
  // we still have stylesheet loads pending.  Otherwise, we'll wait until the
101
  // stylesheets are all done loading.
102
  virtual void MaybeStartLayout(bool aIgnorePendingSheets);
103
104
  virtual nsresult AddAttributes(const char16_t** aNode, Element* aElement);
105
  nsresult AddText(const char16_t* aString, int32_t aLength);
106
107
  virtual bool OnOpenContainer(const char16_t **aAtts,
108
                                 uint32_t aAttsCount,
109
                                 int32_t aNameSpaceID,
110
                                 nsAtom* aTagName,
111
0
                                 uint32_t aLineNumber) { return true; }
112
  // Set the given content as the root element for the created document
113
  //  don't set if root element was already set.
114
  //  return TRUE if this call set the root element
115
  virtual bool SetDocElement(int32_t aNameSpaceID,
116
                               nsAtom *aTagName,
117
                               nsIContent *aContent);
118
0
  virtual bool NotifyForDocElement() { return true; }
119
  virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
120
                                 mozilla::dom::NodeInfo* aNodeInfo,
121
                                 uint32_t aLineNumber, uint32_t aColumnNumber,
122
                                 nsIContent** aResult, bool* aAppendContent,
123
                                 mozilla::dom::FromParser aFromParser);
124
125
  // aParent is allowed to be null here if this is the root content
126
  // being closed
127
  virtual nsresult CloseElement(nsIContent* aContent);
128
129
  virtual nsresult FlushText(bool aReleaseTextNode = true);
130
131
  nsresult AddContentAsLeaf(nsIContent *aContent);
132
133
  nsIContent* GetCurrentContent();
134
  StackNode* GetCurrentStackNode();
135
  nsresult PushContent(nsIContent *aContent);
136
  void PopContent();
137
  bool HaveNotifiedForCurrentContent() const;
138
139
  nsresult FlushTags() override;
140
141
  void UpdateChildCounts() override;
142
143
  void DidAddContent()
144
0
  {
145
0
    if (!mXSLTProcessor && IsTimeToNotify()) {
146
0
      FlushTags();
147
0
    }
148
0
  }
149
150
  // nsContentSink override
151
  virtual nsresult ProcessStyleLinkFromHeader(
152
    const nsAString& aHref,
153
    bool aAlternate,
154
    const nsAString& aTitle,
155
    const nsAString& aType,
156
    const nsAString& aMedia,
157
    const nsAString& aReferrerPolicy) override;
158
159
  // Try to handle an XSLT style link.  If NS_OK is returned and aWasXSLT is not
160
  // null, *aWasXSLT will be set to whether we processed this link as XSLT.
161
  //
162
  // aProcessingInstruction can be null if this information comes from a Link
163
  // header; otherwise it will be the xml-styleshset XML PI that the loading
164
  // information comes from.
165
  virtual nsresult MaybeProcessXSLTLink(
166
    mozilla::dom::ProcessingInstruction* aProcessingInstruction,
167
    const nsAString& aHref,
168
    bool aAlternate,
169
    const nsAString& aTitle,
170
    const nsAString& aType,
171
    const nsAString& aMedia,
172
    const nsAString& aReferrerPolicy,
173
    bool* aWasXSLT = nullptr);
174
175
  nsresult LoadXSLStyleSheet(nsIURI* aUrl);
176
177
  bool CanStillPrettyPrint();
178
179
  nsresult MaybePrettyPrint();
180
181
  bool IsMonolithicContainer(mozilla::dom::NodeInfo* aNodeInfo);
182
183
  nsresult HandleStartElement(const char16_t *aName, const char16_t **aAtts,
184
                              uint32_t aAttsCount, uint32_t aLineNumber,
185
                              uint32_t aColumnNumber, bool aInterruptable);
186
  nsresult HandleEndElement(const char16_t *aName, bool aInterruptable);
187
  nsresult HandleCharacterData(const char16_t *aData, uint32_t aLength,
188
                               bool aInterruptable);
189
190
  nsCOMPtr<nsIContent> mDocElement;
191
  nsCOMPtr<nsIContent> mCurrentHead;  // When set, we're in an XHTML <haed>
192
193
  XMLContentSinkState mState;
194
195
  // The length of the valid data in mText.
196
  int32_t mTextLength;
197
198
  int32_t mNotifyLevel;
199
  RefPtr<nsTextNode> mLastTextNode;
200
201
  uint8_t mPrettyPrintXML : 1;
202
  uint8_t mPrettyPrintHasSpecialRoot : 1;
203
  uint8_t mPrettyPrintHasFactoredElements : 1;
204
  uint8_t mPrettyPrinting : 1;  // True if we called PrettyPrint() and it
205
                                // decided we should in fact prettyprint.
206
  // True to call prevent script execution in the fragment mode.
207
  uint8_t mPreventScriptExecution : 1;
208
209
  nsTArray<StackNode>              mContentStack;
210
211
  nsCOMPtr<nsIDocumentTransformer> mXSLTProcessor;
212
213
  // Holds the children in the prolog until the root element is added, after which they're
214
  // inserted in the document. However, if we're doing an XSLT transform this will
215
  // actually hold all the children of the source document, until the transform is
216
  // finished. After the transform is finished we'll just discard the children.
217
  nsTArray<nsCOMPtr<nsIContent>> mDocumentChildren;
218
219
  static const int NS_ACCUMULATION_BUFFER_SIZE = 4096;
220
  // Our currently accumulated text that we have not flushed to a textnode yet.
221
  char16_t mText[NS_ACCUMULATION_BUFFER_SIZE];
222
};
223
224
#endif // nsXMLContentSink_h__