2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2006-03-31 12:00:42 +04:00
|
|
|
/*
|
|
|
|
* nsIContentSerializer implementation that can be used with an
|
|
|
|
* nsIDocumentEncoder to convert a DOM into plaintext in a nice way
|
|
|
|
* (eg for copy/paste as plaintext).
|
|
|
|
*/
|
|
|
|
|
2000-09-11 09:10:32 +04:00
|
|
|
#ifndef nsPlainTextSerializer_h__
|
|
|
|
#define nsPlainTextSerializer_h__
|
|
|
|
|
2013-05-30 00:43:41 +04:00
|
|
|
#include "mozilla/Attributes.h"
|
2013-03-22 04:05:20 +04:00
|
|
|
#include "nsAutoPtr.h"
|
2000-09-11 09:10:32 +04:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsIAtom.h"
|
2013-03-22 04:05:20 +04:00
|
|
|
#include "nsIContentSerializer.h"
|
2001-01-12 10:26:39 +03:00
|
|
|
#include "nsIDocumentEncoder.h"
|
2013-03-22 04:05:20 +04:00
|
|
|
#include "nsILineBreaker.h"
|
|
|
|
#include "nsString.h"
|
2009-03-20 11:15:35 +03:00
|
|
|
#include "nsTArray.h"
|
Checking in for bug 50742, this change removes the use of XIF in mozilla and replaces the XIF converter with a HTML (and XML) serializer.
Contextual information added to HTML copy and intelligence added to HTML paste in the editor (fixes bugs 47014, 50568 and 46554, and partly (at least) fixes bug 53188).
Code written by vidur, jfrancis, jst, akkana. Tested by jfrancis, akkana, vidur, jst, kin. Reviwed (and super reviewed) by waterson, vidur, kin, jfrancis, jst
2000-10-07 14:57:30 +04:00
|
|
|
|
2014-12-19 20:45:50 +03:00
|
|
|
#include <stack>
|
|
|
|
|
2013-03-22 04:05:20 +04:00
|
|
|
class nsIContent;
|
|
|
|
|
2010-10-23 01:25:22 +04:00
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
class Element;
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
class nsPlainTextSerializer final : public nsIContentSerializer
|
2000-09-11 09:10:32 +04:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
nsPlainTextSerializer();
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIContentSerializer
|
2015-01-13 21:50:12 +03:00
|
|
|
NS_IMETHOD Init(uint32_t flags, uint32_t aWrapColumn,
|
|
|
|
const char* aCharSet, bool aIsCopying,
|
2015-03-21 19:28:04 +03:00
|
|
|
bool aIsWholeDocument) override;
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
NS_IMETHOD AppendText(nsIContent* aText, int32_t aStartOffset,
|
2015-03-21 19:28:04 +03:00
|
|
|
int32_t aEndOffset, nsAString& aStr) override;
|
2010-05-04 17:19:54 +04:00
|
|
|
NS_IMETHOD AppendCDATASection(nsIContent* aCDATASection,
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t aStartOffset, int32_t aEndOffset,
|
2015-03-21 19:28:04 +03:00
|
|
|
nsAString& aStr) override;
|
2010-05-04 17:19:54 +04:00
|
|
|
NS_IMETHOD AppendProcessingInstruction(nsIContent* aPI,
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t aStartOffset,
|
|
|
|
int32_t aEndOffset,
|
2015-03-21 19:28:04 +03:00
|
|
|
nsAString& aStr) override { return NS_OK; }
|
2012-08-22 19:56:38 +04:00
|
|
|
NS_IMETHOD AppendComment(nsIContent* aComment, int32_t aStartOffset,
|
2015-03-21 19:28:04 +03:00
|
|
|
int32_t aEndOffset, nsAString& aStr) override { return NS_OK; }
|
2010-05-04 17:19:54 +04:00
|
|
|
NS_IMETHOD AppendDoctype(nsIContent *aDoctype,
|
2015-03-21 19:28:04 +03:00
|
|
|
nsAString& aStr) override { return NS_OK; }
|
2010-10-23 01:25:22 +04:00
|
|
|
NS_IMETHOD AppendElementStart(mozilla::dom::Element* aElement,
|
|
|
|
mozilla::dom::Element* aOriginalElement,
|
2015-03-21 19:28:04 +03:00
|
|
|
nsAString& aStr) override;
|
2010-10-23 01:25:22 +04:00
|
|
|
NS_IMETHOD AppendElementEnd(mozilla::dom::Element* aElement,
|
2015-03-21 19:28:04 +03:00
|
|
|
nsAString& aStr) override;
|
|
|
|
NS_IMETHOD Flush(nsAString& aStr) override;
|
2002-08-13 22:41:16 +04:00
|
|
|
|
2010-05-04 17:19:54 +04:00
|
|
|
NS_IMETHOD AppendDocumentStart(nsIDocument *aDocument,
|
2015-03-21 19:28:04 +03:00
|
|
|
nsAString& aStr) override;
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2015-01-17 22:16:11 +03:00
|
|
|
private:
|
|
|
|
~nsPlainTextSerializer();
|
2014-06-25 06:09:15 +04:00
|
|
|
|
2012-03-08 18:42:27 +04:00
|
|
|
nsresult GetAttributeValue(nsIAtom* aName, nsString& aValueRet);
|
2014-01-04 19:02:17 +04:00
|
|
|
void AddToLine(const char16_t* aStringToAdd, int32_t aLength);
|
2011-09-29 10:19:26 +04:00
|
|
|
void EndLine(bool softlinebreak, bool aBreakBySpace = false);
|
2012-08-22 19:56:38 +04:00
|
|
|
void EnsureVerticalSpace(int32_t noOfRows);
|
2000-09-11 09:10:32 +04:00
|
|
|
void FlushLine();
|
2011-09-29 10:19:26 +04:00
|
|
|
void OutputQuotesAndIndent(bool stripTrailingSpaces=false);
|
2001-01-12 10:26:39 +03:00
|
|
|
void Output(nsString& aString);
|
2002-03-24 02:54:46 +03:00
|
|
|
void Write(const nsAString& aString);
|
2011-09-29 10:19:26 +04:00
|
|
|
bool IsInPre();
|
|
|
|
bool IsInOL();
|
2012-03-08 18:42:27 +04:00
|
|
|
bool IsCurrentNodeConverted();
|
|
|
|
bool MustSuppressLeaf();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the local name of the element as an atom if the element is an
|
2012-07-30 18:20:58 +04:00
|
|
|
* HTML element and the atom is a static atom. Otherwise, nullptr is returned.
|
2012-03-08 18:42:27 +04:00
|
|
|
*/
|
|
|
|
static nsIAtom* GetIdForContent(nsIContent* aContent);
|
|
|
|
nsresult DoOpenContainer(nsIAtom* aTag);
|
|
|
|
nsresult DoCloseContainer(nsIAtom* aTag);
|
|
|
|
nsresult DoAddLeaf(nsIAtom* aTag);
|
|
|
|
void DoAddText(bool aIsWhitespace, const nsAString& aText);
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2001-01-12 10:26:39 +03:00
|
|
|
// Inlined functions
|
2011-09-29 10:19:26 +04:00
|
|
|
inline bool MayWrap()
|
2001-01-12 10:26:39 +03:00
|
|
|
{
|
|
|
|
return mWrapColumn &&
|
|
|
|
((mFlags & nsIDocumentEncoder::OutputFormatted) ||
|
|
|
|
(mFlags & nsIDocumentEncoder::OutputWrap));
|
|
|
|
}
|
2015-11-27 17:27:00 +03:00
|
|
|
inline bool MayBreakLines()
|
|
|
|
{
|
|
|
|
return !(mFlags & nsIDocumentEncoder::OutputDisallowLineBreaking);
|
|
|
|
}
|
2001-01-12 10:26:39 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
inline bool DoOutput()
|
2001-01-12 10:26:39 +03:00
|
|
|
{
|
2008-02-19 16:17:29 +03:00
|
|
|
return mHeadLevel == 0;
|
2001-01-12 10:26:39 +03:00
|
|
|
}
|
2002-12-19 09:22:55 +03:00
|
|
|
|
|
|
|
// Stack handling functions
|
2011-09-29 10:19:26 +04:00
|
|
|
bool GetLastBool(const nsTArray<bool>& aStack);
|
|
|
|
void SetLastBool(nsTArray<bool>& aStack, bool aValue);
|
|
|
|
void PushBool(nsTArray<bool>& aStack, bool aValue);
|
|
|
|
bool PopBool(nsTArray<bool>& aStack);
|
2013-08-06 18:40:38 +04:00
|
|
|
|
|
|
|
bool ShouldReplaceContainerWithPlaceholder(nsIAtom* aTag);
|
2015-03-10 09:11:55 +03:00
|
|
|
bool IsIgnorableRubyAnnotation(nsIAtom* aTag);
|
2013-08-06 18:40:38 +04:00
|
|
|
|
2014-12-19 20:45:50 +03:00
|
|
|
bool IsElementPreformatted(mozilla::dom::Element* aElement);
|
2015-01-18 01:30:21 +03:00
|
|
|
bool IsElementBlock(mozilla::dom::Element* aElement);
|
2014-12-19 20:45:50 +03:00
|
|
|
|
2015-01-17 22:16:11 +03:00
|
|
|
private:
|
2000-09-11 09:10:32 +04:00
|
|
|
nsString mCurrentLine;
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t mHeadLevel;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mAtFirstColumn;
|
2002-04-17 03:11:33 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mStructs; // Output structs (pref)
|
2001-12-15 02:10:42 +03:00
|
|
|
|
2005-06-01 23:31:47 +04:00
|
|
|
// If we've just written out a cite blockquote, we need to remember it
|
|
|
|
// so we don't duplicate spaces before a <pre wrap> (which mail uses to quote
|
|
|
|
// old messages).
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mHasWrittenCiteBlockquote;
|
2005-06-01 23:31:47 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t mIndent;
|
2000-09-11 09:10:32 +04:00
|
|
|
// mInIndentString keeps a header that has to be written in the indent.
|
|
|
|
// That could be, for instance, the bullet in a bulleted list.
|
|
|
|
nsString mInIndentString;
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t mCiteQuoteLevel;
|
|
|
|
int32_t mFlags;
|
|
|
|
int32_t mFloatingLines; // To store the number of lazy line breaks
|
2000-09-11 09:10:32 +04:00
|
|
|
|
|
|
|
// The wrap column is how many standard sized chars (western languages)
|
|
|
|
// should be allowed on a line. There could be less chars if the chars
|
|
|
|
// are wider than latin chars of more if the chars are more narrow.
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t mWrapColumn;
|
2000-09-11 09:10:32 +04:00
|
|
|
|
|
|
|
// The width of the line as it will appear on the screen (approx.)
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t mCurrentLineWidth;
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2001-07-13 22:45:53 +04:00
|
|
|
// Treat quoted text as though it's preformatted -- don't wrap it.
|
|
|
|
// Having it on a pref is a temporary measure, See bug 69638.
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t mSpanLevel;
|
2001-07-13 22:45:53 +04:00
|
|
|
|
2001-12-15 02:10:42 +03:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t mEmptyLines; // Will be the number of empty lines before
|
2000-09-11 09:10:32 +04:00
|
|
|
// the current. 0 if we are starting a new
|
|
|
|
// line and -1 if we are in a line.
|
2001-12-15 02:10:42 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mInWhitespace;
|
2015-03-04 08:54:40 +03:00
|
|
|
bool mPreFormattedMail; // we're dealing with special DOM
|
|
|
|
// used by Thunderbird code.
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mStartedOutput; // we've produced at least a character
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2002-03-04 13:47:19 +03:00
|
|
|
// While handling a new tag, this variable should remind if any line break
|
|
|
|
// is due because of a closing tag. Setting it to "TRUE" while closing the tags.
|
|
|
|
// Hence opening tags are guaranteed to start with appropriate line breaks.
|
2015-01-18 01:31:59 +03:00
|
|
|
bool mLineBreakDue;
|
|
|
|
|
|
|
|
bool mPreformattedBlockBoundary;
|
2002-03-04 13:47:19 +03:00
|
|
|
|
2015-03-10 09:11:55 +03:00
|
|
|
// Whether the output should include ruby annotations.
|
|
|
|
bool mWithRubyAnnotation;
|
|
|
|
|
2000-09-11 09:10:32 +04:00
|
|
|
nsString mURL;
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t mHeaderStrategy; /* Header strategy (pref)
|
2000-09-11 09:10:32 +04:00
|
|
|
0 = no indention
|
|
|
|
1 = indention, increased with
|
|
|
|
header level (default)
|
|
|
|
2 = numbering and slight indention */
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t mHeaderCounter[7]; /* For header-numbering:
|
2000-09-11 09:10:32 +04:00
|
|
|
Number of previous headers of
|
|
|
|
the same depth and in the same
|
|
|
|
section.
|
|
|
|
mHeaderCounter[1] for <h1> etc. */
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<mozilla::dom::Element> mElement;
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2002-12-19 09:22:55 +03:00
|
|
|
// For handling table rows
|
2016-02-02 18:36:30 +03:00
|
|
|
AutoTArray<bool, 8> mHasWrittenCellsForRow;
|
2002-12-19 09:22:55 +03:00
|
|
|
|
2002-12-14 09:16:56 +03:00
|
|
|
// Values gotten in OpenContainer that is (also) needed in CloseContainer
|
2016-02-02 18:36:30 +03:00
|
|
|
AutoTArray<bool, 8> mIsInCiteBlockquote;
|
2002-12-14 09:16:56 +03:00
|
|
|
|
|
|
|
// The output data
|
2002-03-24 02:54:46 +03:00
|
|
|
nsAString* mOutputString;
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2012-03-08 18:42:27 +04:00
|
|
|
// The tag stack: the stack of tags we're operating on, so we can nest.
|
|
|
|
// The stack only ever points to static atoms, so they don't need to be
|
|
|
|
// refcounted.
|
|
|
|
nsIAtom** mTagStack;
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t mTagStackIndex;
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2014-12-19 20:45:50 +03:00
|
|
|
// The stack indicating whether the elements we've been operating on are
|
|
|
|
// CSS preformatted elements, so that we can tell if the text inside them
|
|
|
|
// should be formatted.
|
|
|
|
std::stack<bool> mPreformatStack;
|
|
|
|
|
2001-11-30 12:19:33 +03:00
|
|
|
// Content in the stack above this index should be ignored:
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t mIgnoreAboveIndex;
|
2001-11-30 12:19:33 +03:00
|
|
|
|
2010-09-29 02:37:30 +04:00
|
|
|
// The stack for ordered lists
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t *mOLStack;
|
|
|
|
uint32_t mOLStackIndex;
|
2000-09-11 09:10:32 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t mULCount;
|
2001-04-10 05:11:39 +04:00
|
|
|
|
2000-09-11 09:10:32 +04:00
|
|
|
nsString mLineBreak;
|
|
|
|
nsCOMPtr<nsILineBreaker> mLineBreaker;
|
2001-01-12 10:26:39 +03:00
|
|
|
|
|
|
|
// Conveniance constant. It would be nice to have it as a const static
|
|
|
|
// variable, but that causes issues with OpenBSD and module unloading.
|
|
|
|
const nsString kSpace;
|
2013-08-06 18:40:38 +04:00
|
|
|
|
|
|
|
// If nsIDocumentEncoder::OutputNonTextContentAsPlaceholder is set, the child
|
|
|
|
// nodes of specific nodes - <iframe>, <canvas>, etc. should be ignored.
|
|
|
|
// mIgnoredChildNodeLevel is used to tell if current node is an ignorable
|
|
|
|
// child node. The initial value of mIgnoredChildNodeLevel is 0. When
|
|
|
|
// serializer enters those specific nodes, mIgnoredChildNodeLevel increases
|
|
|
|
// and is greater than 0. Otherwise when serializer leaves those nodes,
|
|
|
|
// mIgnoredChildNodeLevel decreases.
|
|
|
|
uint32_t mIgnoredChildNodeLevel;
|
2000-09-11 09:10:32 +04:00
|
|
|
};
|
|
|
|
|
2003-03-05 18:08:41 +03:00
|
|
|
nsresult
|
|
|
|
NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer);
|
Checking in for bug 50742, this change removes the use of XIF in mozilla and replaces the XIF converter with a HTML (and XML) serializer.
Contextual information added to HTML copy and intelligence added to HTML paste in the editor (fixes bugs 47014, 50568 and 46554, and partly (at least) fixes bug 53188).
Code written by vidur, jfrancis, jst, akkana. Tested by jfrancis, akkana, vidur, jst, kin. Reviwed (and super reviewed) by waterson, vidur, kin, jfrancis, jst
2000-10-07 14:57:30 +04:00
|
|
|
|
2000-09-11 09:10:32 +04:00
|
|
|
#endif
|