Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | /* |
michael@0 | 7 | * nsIContentSerializer implementation that can be used with an |
michael@0 | 8 | * nsIDocumentEncoder to convert an XML DOM to an XML string that |
michael@0 | 9 | * could be parsed into more or less the original DOM. |
michael@0 | 10 | */ |
michael@0 | 11 | |
michael@0 | 12 | #ifndef nsXMLContentSerializer_h__ |
michael@0 | 13 | #define nsXMLContentSerializer_h__ |
michael@0 | 14 | |
michael@0 | 15 | #include "mozilla/Attributes.h" |
michael@0 | 16 | #include "nsIContentSerializer.h" |
michael@0 | 17 | #include "nsISupportsUtils.h" |
michael@0 | 18 | #include "nsCOMPtr.h" |
michael@0 | 19 | #include "nsTArray.h" |
michael@0 | 20 | #include "nsString.h" |
michael@0 | 21 | |
michael@0 | 22 | #define kIndentStr NS_LITERAL_STRING(" ") |
michael@0 | 23 | #define kEndTag NS_LITERAL_STRING("</") |
michael@0 | 24 | |
michael@0 | 25 | class nsIAtom; |
michael@0 | 26 | class nsIDOMNode; |
michael@0 | 27 | class nsINode; |
michael@0 | 28 | |
michael@0 | 29 | class nsXMLContentSerializer : public nsIContentSerializer { |
michael@0 | 30 | public: |
michael@0 | 31 | nsXMLContentSerializer(); |
michael@0 | 32 | virtual ~nsXMLContentSerializer(); |
michael@0 | 33 | |
michael@0 | 34 | NS_DECL_ISUPPORTS |
michael@0 | 35 | |
michael@0 | 36 | NS_IMETHOD Init(uint32_t flags, uint32_t aWrapColumn, |
michael@0 | 37 | const char* aCharSet, bool aIsCopying, |
michael@0 | 38 | bool aRewriteEncodingDeclaration) MOZ_OVERRIDE; |
michael@0 | 39 | |
michael@0 | 40 | NS_IMETHOD AppendText(nsIContent* aText, int32_t aStartOffset, |
michael@0 | 41 | int32_t aEndOffset, nsAString& aStr) MOZ_OVERRIDE; |
michael@0 | 42 | |
michael@0 | 43 | NS_IMETHOD AppendCDATASection(nsIContent* aCDATASection, |
michael@0 | 44 | int32_t aStartOffset, int32_t aEndOffset, |
michael@0 | 45 | nsAString& aStr) MOZ_OVERRIDE; |
michael@0 | 46 | |
michael@0 | 47 | NS_IMETHOD AppendProcessingInstruction(nsIContent* aPI, |
michael@0 | 48 | int32_t aStartOffset, |
michael@0 | 49 | int32_t aEndOffset, |
michael@0 | 50 | nsAString& aStr) MOZ_OVERRIDE; |
michael@0 | 51 | |
michael@0 | 52 | NS_IMETHOD AppendComment(nsIContent* aComment, int32_t aStartOffset, |
michael@0 | 53 | int32_t aEndOffset, nsAString& aStr) MOZ_OVERRIDE; |
michael@0 | 54 | |
michael@0 | 55 | NS_IMETHOD AppendDoctype(nsIContent *aDoctype, |
michael@0 | 56 | nsAString& aStr) MOZ_OVERRIDE; |
michael@0 | 57 | |
michael@0 | 58 | NS_IMETHOD AppendElementStart(mozilla::dom::Element* aElement, |
michael@0 | 59 | mozilla::dom::Element* aOriginalElement, |
michael@0 | 60 | nsAString& aStr) MOZ_OVERRIDE; |
michael@0 | 61 | |
michael@0 | 62 | NS_IMETHOD AppendElementEnd(mozilla::dom::Element* aElement, |
michael@0 | 63 | nsAString& aStr) MOZ_OVERRIDE; |
michael@0 | 64 | |
michael@0 | 65 | NS_IMETHOD Flush(nsAString& aStr) MOZ_OVERRIDE { return NS_OK; } |
michael@0 | 66 | |
michael@0 | 67 | NS_IMETHOD AppendDocumentStart(nsIDocument *aDocument, |
michael@0 | 68 | nsAString& aStr) MOZ_OVERRIDE; |
michael@0 | 69 | |
michael@0 | 70 | protected: |
michael@0 | 71 | |
michael@0 | 72 | /** |
michael@0 | 73 | * Appends a char16_t character and increments the column position |
michael@0 | 74 | */ |
michael@0 | 75 | void AppendToString(const char16_t aChar, |
michael@0 | 76 | nsAString& aOutputStr); |
michael@0 | 77 | |
michael@0 | 78 | /** |
michael@0 | 79 | * Appends a nsAString string and increments the column position |
michael@0 | 80 | */ |
michael@0 | 81 | void AppendToString(const nsAString& aStr, |
michael@0 | 82 | nsAString& aOutputStr); |
michael@0 | 83 | |
michael@0 | 84 | /** |
michael@0 | 85 | * Appends a string by replacing all line-endings |
michael@0 | 86 | * by mLineBreak, except in the case of raw output. |
michael@0 | 87 | * It increments the column position. |
michael@0 | 88 | */ |
michael@0 | 89 | void AppendToStringConvertLF(const nsAString& aStr, |
michael@0 | 90 | nsAString& aOutputStr); |
michael@0 | 91 | |
michael@0 | 92 | /** |
michael@0 | 93 | * Appends a string by wrapping it when necessary. |
michael@0 | 94 | * It updates the column position. |
michael@0 | 95 | */ |
michael@0 | 96 | void AppendToStringWrapped(const nsASingleFragmentString& aStr, |
michael@0 | 97 | nsAString& aOutputStr); |
michael@0 | 98 | |
michael@0 | 99 | /** |
michael@0 | 100 | * Appends a string by formating and wrapping it when necessary |
michael@0 | 101 | * It updates the column position. |
michael@0 | 102 | */ |
michael@0 | 103 | void AppendToStringFormatedWrapped(const nsASingleFragmentString& aStr, |
michael@0 | 104 | nsAString& aOutputStr); |
michael@0 | 105 | |
michael@0 | 106 | // used by AppendToStringWrapped |
michael@0 | 107 | void AppendWrapped_WhitespaceSequence( |
michael@0 | 108 | nsASingleFragmentString::const_char_iterator &aPos, |
michael@0 | 109 | const nsASingleFragmentString::const_char_iterator aEnd, |
michael@0 | 110 | const nsASingleFragmentString::const_char_iterator aSequenceStart, |
michael@0 | 111 | nsAString &aOutputStr); |
michael@0 | 112 | |
michael@0 | 113 | // used by AppendToStringFormatedWrapped |
michael@0 | 114 | void AppendFormatedWrapped_WhitespaceSequence( |
michael@0 | 115 | nsASingleFragmentString::const_char_iterator &aPos, |
michael@0 | 116 | const nsASingleFragmentString::const_char_iterator aEnd, |
michael@0 | 117 | const nsASingleFragmentString::const_char_iterator aSequenceStart, |
michael@0 | 118 | bool &aMayIgnoreStartOfLineWhitespaceSequence, |
michael@0 | 119 | nsAString &aOutputStr); |
michael@0 | 120 | |
michael@0 | 121 | // used by AppendToStringWrapped and AppendToStringFormatedWrapped |
michael@0 | 122 | void AppendWrapped_NonWhitespaceSequence( |
michael@0 | 123 | nsASingleFragmentString::const_char_iterator &aPos, |
michael@0 | 124 | const nsASingleFragmentString::const_char_iterator aEnd, |
michael@0 | 125 | const nsASingleFragmentString::const_char_iterator aSequenceStart, |
michael@0 | 126 | bool &aMayIgnoreStartOfLineWhitespaceSequence, |
michael@0 | 127 | bool &aSequenceStartAfterAWhiteSpace, |
michael@0 | 128 | nsAString &aOutputStr); |
michael@0 | 129 | |
michael@0 | 130 | /** |
michael@0 | 131 | * add mLineBreak to the string |
michael@0 | 132 | * It updates the column position and other flags. |
michael@0 | 133 | */ |
michael@0 | 134 | void AppendNewLineToString(nsAString& aOutputStr); |
michael@0 | 135 | |
michael@0 | 136 | |
michael@0 | 137 | /** |
michael@0 | 138 | * Appends a string by translating entities |
michael@0 | 139 | * It doesn't increment the column position |
michael@0 | 140 | */ |
michael@0 | 141 | virtual void AppendAndTranslateEntities(const nsAString& aStr, |
michael@0 | 142 | nsAString& aOutputStr); |
michael@0 | 143 | |
michael@0 | 144 | /** |
michael@0 | 145 | * retrieve the text content of the node and append it to the given string |
michael@0 | 146 | * It doesn't increment the column position |
michael@0 | 147 | */ |
michael@0 | 148 | nsresult AppendTextData(nsIContent* aNode, |
michael@0 | 149 | int32_t aStartOffset, |
michael@0 | 150 | int32_t aEndOffset, |
michael@0 | 151 | nsAString& aStr, |
michael@0 | 152 | bool aTranslateEntities); |
michael@0 | 153 | |
michael@0 | 154 | virtual nsresult PushNameSpaceDecl(const nsAString& aPrefix, |
michael@0 | 155 | const nsAString& aURI, |
michael@0 | 156 | nsIContent* aOwner); |
michael@0 | 157 | void PopNameSpaceDeclsFor(nsIContent* aOwner); |
michael@0 | 158 | |
michael@0 | 159 | /** |
michael@0 | 160 | * The problem that ConfirmPrefix fixes is that anyone can insert nodes |
michael@0 | 161 | * through the DOM that have a namespace URI and a random or empty or |
michael@0 | 162 | * previously existing prefix that's totally unrelated to the prefixes |
michael@0 | 163 | * declared at that point through xmlns attributes. So what ConfirmPrefix |
michael@0 | 164 | * does is ensure that we can map aPrefix to the namespace URI aURI (for |
michael@0 | 165 | * example, that the prefix is not already mapped to some other namespace). |
michael@0 | 166 | * aPrefix will be adjusted, if necessary, so the value of the prefix |
michael@0 | 167 | * _after_ this call is what should be serialized. |
michael@0 | 168 | * @param aPrefix the prefix that may need adjusting |
michael@0 | 169 | * @param aURI the namespace URI we want aPrefix to point to |
michael@0 | 170 | * @param aElement the element we're working with (needed for proper default |
michael@0 | 171 | * namespace handling) |
michael@0 | 172 | * @param aIsAttribute true if we're confirming a prefix for an attribute. |
michael@0 | 173 | * @return true if we need to push the (prefix, uri) pair on the namespace |
michael@0 | 174 | * stack (note that this can happen even if the prefix is |
michael@0 | 175 | * empty). |
michael@0 | 176 | */ |
michael@0 | 177 | bool ConfirmPrefix(nsAString& aPrefix, |
michael@0 | 178 | const nsAString& aURI, |
michael@0 | 179 | nsIContent* aElement, |
michael@0 | 180 | bool aIsAttribute); |
michael@0 | 181 | /** |
michael@0 | 182 | * GenerateNewPrefix generates a new prefix and writes it to aPrefix |
michael@0 | 183 | */ |
michael@0 | 184 | void GenerateNewPrefix(nsAString& aPrefix); |
michael@0 | 185 | |
michael@0 | 186 | uint32_t ScanNamespaceDeclarations(nsIContent* aContent, |
michael@0 | 187 | nsIContent *aOriginalElement, |
michael@0 | 188 | const nsAString& aTagNamespaceURI); |
michael@0 | 189 | |
michael@0 | 190 | virtual void SerializeAttributes(nsIContent* aContent, |
michael@0 | 191 | nsIContent *aOriginalElement, |
michael@0 | 192 | nsAString& aTagPrefix, |
michael@0 | 193 | const nsAString& aTagNamespaceURI, |
michael@0 | 194 | nsIAtom* aTagName, |
michael@0 | 195 | nsAString& aStr, |
michael@0 | 196 | uint32_t aSkipAttr, |
michael@0 | 197 | bool aAddNSAttr); |
michael@0 | 198 | |
michael@0 | 199 | void SerializeAttr(const nsAString& aPrefix, |
michael@0 | 200 | const nsAString& aName, |
michael@0 | 201 | const nsAString& aValue, |
michael@0 | 202 | nsAString& aStr, |
michael@0 | 203 | bool aDoEscapeEntities); |
michael@0 | 204 | |
michael@0 | 205 | bool IsJavaScript(nsIContent * aContent, |
michael@0 | 206 | nsIAtom* aAttrNameAtom, |
michael@0 | 207 | int32_t aAttrNamespaceID, |
michael@0 | 208 | const nsAString& aValueString); |
michael@0 | 209 | |
michael@0 | 210 | /** |
michael@0 | 211 | * This method can be redefined to check if the element can be serialized. |
michael@0 | 212 | * It is called when the serialization of the start tag is asked |
michael@0 | 213 | * (AppendElementStart) |
michael@0 | 214 | * In this method you can also force the formating |
michael@0 | 215 | * by setting aForceFormat to true. |
michael@0 | 216 | * @return boolean true if the element can be output |
michael@0 | 217 | */ |
michael@0 | 218 | virtual bool CheckElementStart(nsIContent * aContent, |
michael@0 | 219 | bool & aForceFormat, |
michael@0 | 220 | nsAString& aStr); |
michael@0 | 221 | |
michael@0 | 222 | /** |
michael@0 | 223 | * this method is responsible to finish the start tag, |
michael@0 | 224 | * in particulary to append the "greater than" sign |
michael@0 | 225 | */ |
michael@0 | 226 | virtual void AppendEndOfElementStart(nsIContent *aOriginalElement, |
michael@0 | 227 | nsIAtom * aName, |
michael@0 | 228 | int32_t aNamespaceID, |
michael@0 | 229 | nsAString& aStr); |
michael@0 | 230 | |
michael@0 | 231 | /** |
michael@0 | 232 | * This method can be redefine to serialize additional things just after |
michael@0 | 233 | * after the serialization ot the start tag. |
michael@0 | 234 | * (called at the end of AppendElementStart) |
michael@0 | 235 | */ |
michael@0 | 236 | virtual void AfterElementStart(nsIContent * aContent, |
michael@0 | 237 | nsIContent *aOriginalElement, |
michael@0 | 238 | nsAString& aStr) { }; |
michael@0 | 239 | |
michael@0 | 240 | /** |
michael@0 | 241 | * This method can be redefined to check if the element can be serialized. |
michael@0 | 242 | * It is called when the serialization of the end tag is asked |
michael@0 | 243 | * (AppendElementEnd) |
michael@0 | 244 | * In this method you can also force the formating |
michael@0 | 245 | * by setting aForceFormat to true. |
michael@0 | 246 | * @return boolean true if the element can be output |
michael@0 | 247 | */ |
michael@0 | 248 | virtual bool CheckElementEnd(nsIContent * aContent, |
michael@0 | 249 | bool & aForceFormat, |
michael@0 | 250 | nsAString& aStr); |
michael@0 | 251 | |
michael@0 | 252 | /** |
michael@0 | 253 | * This method can be redefine to serialize additional things just after |
michael@0 | 254 | * after the serialization ot the end tag. |
michael@0 | 255 | * (called at the end of AppendElementStart) |
michael@0 | 256 | */ |
michael@0 | 257 | virtual void AfterElementEnd(nsIContent * aContent, |
michael@0 | 258 | nsAString& aStr) { }; |
michael@0 | 259 | |
michael@0 | 260 | /** |
michael@0 | 261 | * Returns true if a line break should be inserted before an element open tag |
michael@0 | 262 | */ |
michael@0 | 263 | virtual bool LineBreakBeforeOpen(int32_t aNamespaceID, nsIAtom* aName); |
michael@0 | 264 | |
michael@0 | 265 | /** |
michael@0 | 266 | * Returns true if a line break should be inserted after an element open tag |
michael@0 | 267 | */ |
michael@0 | 268 | virtual bool LineBreakAfterOpen(int32_t aNamespaceID, nsIAtom* aName); |
michael@0 | 269 | |
michael@0 | 270 | /** |
michael@0 | 271 | * Returns true if a line break should be inserted after an element close tag |
michael@0 | 272 | */ |
michael@0 | 273 | virtual bool LineBreakBeforeClose(int32_t aNamespaceID, nsIAtom* aName); |
michael@0 | 274 | |
michael@0 | 275 | /** |
michael@0 | 276 | * Returns true if a line break should be inserted after an element close tag |
michael@0 | 277 | */ |
michael@0 | 278 | virtual bool LineBreakAfterClose(int32_t aNamespaceID, nsIAtom* aName); |
michael@0 | 279 | |
michael@0 | 280 | /** |
michael@0 | 281 | * add intendation. Call only in the case of formating and if the current |
michael@0 | 282 | * position is at 0. It updates the column position. |
michael@0 | 283 | */ |
michael@0 | 284 | void AppendIndentation(nsAString& aStr); |
michael@0 | 285 | void IncrIndentation(nsIAtom* aName); |
michael@0 | 286 | void DecrIndentation(nsIAtom* aName); |
michael@0 | 287 | |
michael@0 | 288 | // Functions to check for newlines that needs to be added between nodes in |
michael@0 | 289 | // the root of a document. See mAddNewlineForRootNode |
michael@0 | 290 | void MaybeAddNewlineForRootNode(nsAString& aStr); |
michael@0 | 291 | void MaybeFlagNewlineForRootNode(nsINode* aNode); |
michael@0 | 292 | |
michael@0 | 293 | // Functions to check if we enter in or leave from a preformated content |
michael@0 | 294 | virtual void MaybeEnterInPreContent(nsIContent* aNode); |
michael@0 | 295 | virtual void MaybeLeaveFromPreContent(nsIContent* aNode); |
michael@0 | 296 | |
michael@0 | 297 | int32_t mPrefixIndex; |
michael@0 | 298 | |
michael@0 | 299 | struct NameSpaceDecl { |
michael@0 | 300 | nsString mPrefix; |
michael@0 | 301 | nsString mURI; |
michael@0 | 302 | nsIContent* mOwner; |
michael@0 | 303 | }; |
michael@0 | 304 | |
michael@0 | 305 | nsTArray<NameSpaceDecl> mNameSpaceStack; |
michael@0 | 306 | |
michael@0 | 307 | // nsIDocumentEncoder flags |
michael@0 | 308 | uint32_t mFlags; |
michael@0 | 309 | |
michael@0 | 310 | // characters to use for line break |
michael@0 | 311 | nsString mLineBreak; |
michael@0 | 312 | |
michael@0 | 313 | // The charset that was passed to Init() |
michael@0 | 314 | nsCString mCharset; |
michael@0 | 315 | |
michael@0 | 316 | // current column position on the current line |
michael@0 | 317 | uint32_t mColPos; |
michael@0 | 318 | |
michael@0 | 319 | // true = pretty formating should be done (OutputFormated flag) |
michael@0 | 320 | bool mDoFormat; |
michael@0 | 321 | |
michael@0 | 322 | // true = no formatting,(OutputRaw flag) |
michael@0 | 323 | // no newline convertion and no rewrap long lines even if OutputWrap is set. |
michael@0 | 324 | bool mDoRaw; |
michael@0 | 325 | |
michael@0 | 326 | // true = wrapping should be done (OutputWrap flag) |
michael@0 | 327 | bool mDoWrap; |
michael@0 | 328 | |
michael@0 | 329 | // number of maximum column in a line, in the wrap mode |
michael@0 | 330 | uint32_t mMaxColumn; |
michael@0 | 331 | |
michael@0 | 332 | // current indent value |
michael@0 | 333 | nsString mIndent; |
michael@0 | 334 | |
michael@0 | 335 | // this is the indentation level after the indentation reached |
michael@0 | 336 | // the maximum length of indentation |
michael@0 | 337 | int32_t mIndentOverflow; |
michael@0 | 338 | |
michael@0 | 339 | // says if the indentation has been already added on the current line |
michael@0 | 340 | bool mIsIndentationAddedOnCurrentLine; |
michael@0 | 341 | |
michael@0 | 342 | // the string which is currently added is in an attribute |
michael@0 | 343 | bool mInAttribute; |
michael@0 | 344 | |
michael@0 | 345 | // true = a newline character should be added. It's only |
michael@0 | 346 | // useful when serializing root nodes. see MaybeAddNewlineForRootNode and |
michael@0 | 347 | // MaybeFlagNewlineForRootNode |
michael@0 | 348 | bool mAddNewlineForRootNode; |
michael@0 | 349 | |
michael@0 | 350 | // Indicates that a space will be added if and only if content is |
michael@0 | 351 | // continued on the same line while serializing source. Otherwise, |
michael@0 | 352 | // the newline character acts as the whitespace and no space is needed. |
michael@0 | 353 | // used when mDoFormat = true |
michael@0 | 354 | bool mAddSpace; |
michael@0 | 355 | |
michael@0 | 356 | // says that if the next string to add contains a newline character at the |
michael@0 | 357 | // begining, then this newline character should be ignored, because a |
michael@0 | 358 | // such character has already been added into the output string |
michael@0 | 359 | bool mMayIgnoreLineBreakSequence; |
michael@0 | 360 | |
michael@0 | 361 | bool mBodyOnly; |
michael@0 | 362 | int32_t mInBody; |
michael@0 | 363 | |
michael@0 | 364 | // number of nested elements which have preformated content |
michael@0 | 365 | int32_t mPreLevel; |
michael@0 | 366 | }; |
michael@0 | 367 | |
michael@0 | 368 | nsresult |
michael@0 | 369 | NS_NewXMLContentSerializer(nsIContentSerializer** aSerializer); |
michael@0 | 370 | |
michael@0 | 371 | #endif |